diff options
69 files changed, 39008 insertions, 39008 deletions
diff --git a/docview/components/richtext/README.txt b/docview/components/richtext/README.txt index 04379657..fd2d3a03 100644 --- a/docview/components/richtext/README.txt +++ b/docview/components/richtext/README.txt @@ -1,81 +1,81 @@ -TRichTextView component
-for fpGUI Toolkit
-
-
-Summary
--------
-This component displays 'rich' text, with various fonts, colors,
-styles and alignment.
-
-The major features are:
- Fast, accurate drawing of text
-
-Features to come...
- Selection and copy
- Built-in default popup menu
-
-
-Using the component
--------------------
-Put a component on your form. Adjust the properties as you see fit.
-At runtime, load the text into the control using AddText, AddParagraph,
-and Clear.
-
-
-Formatting syntax
------------------
-This is a HTML-like set of tags. But note that tag pairs don't have to
-match up.
-
-Implemented tags:
-
- <b> </b> bold on, off
- <u> </u> underline on, off
- <i> </i> italic on, off
- <h1> <h2> <h3> heading 1-3, set with Heading1Font etc
- </h> changes heading text back to normal text
- <tt> </tt> fixed font
- <color x> </color> set text to the color xxx, where xxx is a convenience
- color (red, green, blue, yellow, black, purple, cyan) or a
- color value #RRGGBB like #008000 (which is a shade of
- green).
- <red> sets text color to red (convenience tag)
- <blue> sets text color to blue (convenience tag)
- <green> sets text color to green (convenience tag)
- <black> sets text color to black (convenience tag)
- <backcolor xxx> sets the background color of text to xxx
- </backcolor>
- <align> default left text alignment
- <align left> Same as above. Left text alignment
- <align center> Centered text alignment
- <align right> Right text alignment
- <leftmargin xx> Text will begin xx spaces from the left
- <link linktext> </link>
- Start, End link.
- The OnClickLink and OnOverLink events are called with linktext
- <image x> Display image x from associated TImageList
- <wrap no> No text wrapping will occur
- <wrap yes> Text wrapping is enabled again.
- <font "font name" x>
- Where "font name" is the name of the font, and x is the
- point size of the font.
-
-
-Not implemented yet:
- <justify> full text justification
- <rightmargin xx> Text will begin xx spaces from the left
- <defaultalign> Set alignment back to the default RichTextSettings.DefaultAlignment
- value
-
-
-Example
--------
-RichText.AddParagraph( '<h1>This is a big heading</h>' );
-RichText.AddParagraph( 'Here is some <b>bold</b> text' );
-
-
-Problems/limitations
---------------------
-Yes, there probably are some. :)
-
+TRichTextView component +for fpGUI Toolkit + + +Summary +------- +This component displays 'rich' text, with various fonts, colors, +styles and alignment. + +The major features are: + Fast, accurate drawing of text + +Features to come... + Selection and copy + Built-in default popup menu + + +Using the component +------------------- +Put a component on your form. Adjust the properties as you see fit. +At runtime, load the text into the control using AddText, AddParagraph, +and Clear. + + +Formatting syntax +----------------- +This is a HTML-like set of tags. But note that tag pairs don't have to +match up. + +Implemented tags: + + <b> </b> bold on, off + <u> </u> underline on, off + <i> </i> italic on, off + <h1> <h2> <h3> heading 1-3, set with Heading1Font etc + </h> changes heading text back to normal text + <tt> </tt> fixed font + <color x> </color> set text to the color xxx, where xxx is a convenience + color (red, green, blue, yellow, black, purple, cyan) or a + color value #RRGGBB like #008000 (which is a shade of + green). + <red> sets text color to red (convenience tag) + <blue> sets text color to blue (convenience tag) + <green> sets text color to green (convenience tag) + <black> sets text color to black (convenience tag) + <backcolor xxx> sets the background color of text to xxx + </backcolor> + <align> default left text alignment + <align left> Same as above. Left text alignment + <align center> Centered text alignment + <align right> Right text alignment + <leftmargin xx> Text will begin xx spaces from the left + <link linktext> </link> + Start, End link. + The OnClickLink and OnOverLink events are called with linktext + <image x> Display image x from associated TImageList + <wrap no> No text wrapping will occur + <wrap yes> Text wrapping is enabled again. + <font "font name" x> + Where "font name" is the name of the font, and x is the + point size of the font. + + +Not implemented yet: + <justify> full text justification + <rightmargin xx> Text will begin xx spaces from the left + <defaultalign> Set alignment back to the default RichTextSettings.DefaultAlignment + value + + +Example +------- +RichText.AddParagraph( '<h1>This is a big heading</h>' ); +RichText.AddParagraph( 'Here is some <b>bold</b> text' ); + + +Problems/limitations +-------------------- +Yes, there probably are some. :) +
\ No newline at end of file diff --git a/docview/components/richtext/RichTextPrintUnit.pas b/docview/components/richtext/RichTextPrintUnit.pas index 01746c68..3f963a63 100644 --- a/docview/components/richtext/RichTextPrintUnit.pas +++ b/docview/components/richtext/RichTextPrintUnit.pas @@ -1,75 +1,75 @@ -Unit RichTextPrintUnit;
-
-Interface
-
-uses
- Graphics,
- RichTextStyleUnit;
-
-// Prints the specified rich text, starting at page position PageY.
-// Starts new pages as needed; when done, PageY is the final position used
-// on the final page.
-Procedure PrintRichText( Text: PChar;
- Images: TImageList;
- Settings: TRichTextSettings;
- var PageY: longint );
-
-Implementation
-
-uses
- Classes,
- Printers,
- CanvasFontManager,
- RichTextLayoutUnit, RichTextDisplayUnit, Forms
- ;
-
-Procedure PrintRichText( Text: PChar;
- Images: TImageList;
- Settings: TRichTextSettings;
- var PageY: longint );
-var
- Layout: TRichTextLayout;
- FontManager: TCanvasFontManager;
- LineIndex: longint;
- Y: longint;
- FinishLine: longint;
- FinishY: longint;
-Begin
- FontManager := TCanvasFontManager.Create( Printer.Canvas,
- false // don't allow bitmap fonts
- );
-
- Layout := TRichTextLayout.Create( Text,
- Images,
- Settings,
- FontManager,
- Printer.PageWidth );
-
- LineIndex := 0;
- Y := PageY;
- repeat
- PrintRichTextLayout( FontManager,
- Layout,
- LineIndex,
- FinishLine,
- Y,
- FinishY );
- LineIndex := FinishLine;
- Y := FinishY;
-
- if LineIndex < Layout.FNumLines then
- begin
- // didn't all fit on page, so new page
- Printer.NewPage;
- Y := Printer.PageHeight - 1;
- end;
-
- until LineIndex >= Layout.FNumLines;
-
- Layout.Destroy;
- FontManager.Destroy;
- PageY := Y;
-end;
-
-Initialization
-End.
+Unit RichTextPrintUnit; + +Interface + +uses + Graphics, + RichTextStyleUnit; + +// Prints the specified rich text, starting at page position PageY. +// Starts new pages as needed; when done, PageY is the final position used +// on the final page. +Procedure PrintRichText( Text: PChar; + Images: TImageList; + Settings: TRichTextSettings; + var PageY: longint ); + +Implementation + +uses + Classes, + Printers, + CanvasFontManager, + RichTextLayoutUnit, RichTextDisplayUnit, Forms + ; + +Procedure PrintRichText( Text: PChar; + Images: TImageList; + Settings: TRichTextSettings; + var PageY: longint ); +var + Layout: TRichTextLayout; + FontManager: TCanvasFontManager; + LineIndex: longint; + Y: longint; + FinishLine: longint; + FinishY: longint; +Begin + FontManager := TCanvasFontManager.Create( Printer.Canvas, + false // don't allow bitmap fonts + ); + + Layout := TRichTextLayout.Create( Text, + Images, + Settings, + FontManager, + Printer.PageWidth ); + + LineIndex := 0; + Y := PageY; + repeat + PrintRichTextLayout( FontManager, + Layout, + LineIndex, + FinishLine, + Y, + FinishY ); + LineIndex := FinishLine; + Y := FinishY; + + if LineIndex < Layout.FNumLines then + begin + // didn't all fit on page, so new page + Printer.NewPage; + Y := Printer.PageHeight - 1; + end; + + until LineIndex >= Layout.FNumLines; + + Layout.Destroy; + FontManager.Destroy; + PageY := Y; +end; + +Initialization +End. diff --git a/docview/docs/INF_article.txt b/docview/docs/INF_article.txt index d5c5ffd0..c6eb5f03 100644 --- a/docview/docs/INF_article.txt +++ b/docview/docs/INF_article.txt @@ -1,593 +1,593 @@ -
- Information on reading the INF file format
- ==========================================
-
-Author: unknown
-Date: unknown
-
-
-This article is intended to provide the reader with enough information
-to read and search the HLP/INF file format. Support is not provided
-for constructing your own INF files.
-
-The INF and HLP file format are exactly the same except for the
-switching of two bytes in the header. Therefore all the information in
-this article applies to both HLP and INF files. The difference between
-the two will be explained later. I will, however, use the term "INF
-format" to distinguish between OS/2 HLP files and Windows HLP files.
-
-This article will be divided into three main parts. First there will
-be an overview of the file format. Second there will be information on
-accessing parts of this format, including code samples. Third will be
-information on searching the INF format.
-
-Note that to understand a lot of the concepts in displaying panels,
-an understanding of the IPF Guide and Reference is necessary. This
-will give an understanding of the ways in which panels can be modified
-in terms of sizes, styles, etc.
-
-
-Overview
-========
-
- [This is where I will put Stan's document]
-
-Accessing Information in the INF/HLP file
------------------------------------------
-The next part of this article is organized as if you are writing your
-own INF/HLP viewer. It will provide explanations on how to do the
-following things:
-
-1. Read in header information. This will allow you to display the
- title and access the rest of the information in the panel.
-
-2. Read in and index the vocabulary.
-
-3. Read in the Cell Offset Table. This will be used later to display
- panels.
-
-4. Read in the table of contents. Explanations will be given for two
- methods of accessing the table of contents. The first is from
- memory. This method is useful if you are reading the entire table
- of contents at once to display it, or if your application will
- provide primary access to panels through the table of contents. The
- second method of accessing table of contents entries is directly
- from the file. This method is useful for linking and for displaying
- a panel initially when a file is opened. In OS/2, VIEW uses the
- first method whereas displaying help for an application uses the
- second method.
-
-5. Display the titles of all panels in the file. Titles will not be
- stored because access to the table of contents is provided by
- index, not by title. There is a lot of extra information in the
- table of contents entries that will not be used until a cell is
- actually displayed.
-
-6. Display a panel. This will be the most involved explanation.
- Displaying a panel actually requires retrieving a lot of
- information from the table of contents and then reading and
- formatting the data within the panel.
-
-Note that this makes some basic assumptions that you are going to use
-the file in a similar manner as OS/2s VIEW program and Help Manager.
-
-
-Headers
-=======
-The first step in accessing information in the file is to read in the
-header. Figures 1 and 2 show the structures used to acccess the
-regular and extended headers. The extended header is not in every
-file. It can be detected by checking the ExtHeaderOffset in the
-DOCHEADER structure. If the ExtHeaderOffset is greater than 0, then it
-is the file offset of the extended header. The following code fragment
-opens the file and reads the DOCHEADER and the EXTHEADER if necessary.
-
-DOCHEADER DocHeader;
-EXTHEADER ExtHeader;
-FILE* fpointer;
-CHAR* FileName;
-
-fpointer = fopen(FileName,"rb");
-fread(&DocHeader,sizeof(DOCHEADER),1,fpointer);
-if (DocHeader.ExtHeaderOffset > 0) {
- fseek(fpointer, DocHeader.ExtHeaderOffset, SEEK_SET);
- fread(&ExtHeader,sizeof(EXTHEADER),1,fpointer);
-}
-
-The DOCHEADER contains all of the information needed to access data
-within the file. At this point, though, there are only a couple
-fields we are concerned about. The first is the FileCTRLWord. This
-field indicates the type of file. If it is 0x01505348 it is an INF file;
-If it is 0x10505348, it is a HLP file. The other field of use right now
-is the Title; this is simply a null-terminated string containing
-the title of the document. One interesting note is that although
-the title for a HLP file is normally specified in an application,
-there still is a title in the HLP file if the writer specified
-a :title. tag.
-
-
-Vocabulary
-==========
-Once the DOCHEADER is obtained, the next step is to read the vocabulary.
-All references to the vocabulary in the INF/HLP file are made via an
-index value. This index, however, is not in the file so it must be
-built. The following code fragment reads in the vocabulary and builds
-an index to it.
-
-PULONG pulVocabIndex;
-PCHAR pchVocab;
-ULONG ulVocabPointer;
-INT i;
-
-pchVocab = malloc(DocHeader.CLVTSize);
-pulVocabIndex = malloc(DocHeader.CLVTNumWords*(sizeof(ULONG));
-
-fseek(fpointer, DocHeader.CLVTOffset,SEEK_SET);
-fread(pchVocab, DocHeader.CLVTSize, 1, fpointer);
-
-ulVocabPointer = 0;
-for (i=0;i< DocHeader.CLVTNumWords ;i++ ) {
- pulVocabIndex[i] = ulVocabPointer;
- ulVocabPointer += pchVocab[ulVocabPointer];
-} /* endfor */
-
-Remember that when referencing the vocabulary, the first byte contains the
-length of the word, including the first byte. Here is the result of the
-above code sample with a vocabulary of {you, can, develop}.
-
-Example:
---------
-pchVocab -> 4can8develop4you
- │ │ │
- │ └───┐ ┌┘
- └─────┐ │ │
-pulVocabIndex -> {0,4,12}
-
-Given any index into the vocabulary, you can then reference the
-appropriate word.
-
-
-Cell Offset Table
-=================
-The Cell Offset Table will be read next. It will be used later to
-get the file offsets of the cells within each panel. The information
-needed to obtain the Cell Offset Table is contained in the DOCHEADER.
-The pertinent fields are NumCell and COTOffset. The following code
-fragment retrieves the Cell Offset Table from the file.
-
-PULONG pulCOT;
-
-pulCOT = malloc(DocHeader.NumCell*sizeof(ULONG));
-fseek(fpointer, DocHeader.COTOffset, SEEK_SET);
-fread(pulCOT, DocHeader.NumCell*sizeof(ULONG), 1, fpointer);
-
-
-Table Of Contents
-=================
-The next step is to read the table of contents into memory.
-The DOCHEADER contains all the values necessary to read the table of
-contents. TOCOffset contains the file offset of the table of contents
-and TOCSize contains the size. The table of contents is read in a
-similar manner to the vocabulary; that is, it is read into memory
-and then indexed. The following code fragments reads the table
-of contents into memory.
-
-PULONG pulTOCIndex;
-PBYTE pbTOC;
-ULONG ulTOCPointer;
-INT i;
-
-pbTOC = malloc(DocHeader.TOCSize);
-pulTOCIndex = malloc(DocHeader.NumTOCEntry*(sizeof(ULONG));
-
-fseek(fpointer, DocHeader.TOCOffset,SEEK_SET);
-fread(pbTOC, DocHeader.TOCSize, 1, fpointer);
-
-ulTOCPointer = pbTOC;
-for (i=0;i< DocHeader.NumTOCEntry ;i++ ) {
- pulTOCIndex[i] = ulTOCPointer;
- ulTOCPointer += (BYTE) *pvTOC;
-} /* endfor */
-
-Each entry in the TOC index is an address of a TOC entry. Once the TOC
-is in memory, individual TOC items can be referenced. Note that this
-is not the only way to reference the TOC. There is also a TOC Ofset
-Table which provides file offsets to individual TOC items. This is used
-when you need to reference a panel individually by its TOC index.
-This is true when linking and when opening a HLP or INF file without
-display the table of contents first. The following code fragment
-retrieves the TOC Offset Table.
-
-PULONG pulTOCOffsetTable;
-
-pulTOCOffsetTable = malloc(DocHeader.NumTOCEntry*sizeof(ULONG));
-
-fseek(fpointer, DocHeader.OfsTiTICOfsTable,SEEK_SET);
-fread(pulTOCOffsetTable, DocHeader.NumTOCEntry*sizeof(ULONG), 1, fpointer);
-
-Once you have access to a table of contents entry, you must then read
-in the data contained there. This is not very straightforward due
-to the fact that TOC entries can very greatly in length. At this point,
-though, the important thing to read from the TOC entries are the titles.
-You will probably not want to use the header information until you need
-to display a panel. The following code fragment just reads the title
-given that the table of contents is in memory and the entry we want
-to access is i. It also checks the the extended header (if it exists)
-to determine whether or not the entry is a parent. This will allow
-you to display some sort of indicator that the entry can be expanded
-to display its children, similar to the way the help manager does.
-
-TOCIN TocIn;
-USHORT NumBytes;
-BOOL fParent = FALSE;
-PSZ pszTitle;
-USHORT TOCControlWord;
-
-memcpy(&TOCIn, pulTOCIndex[i], sizeof(TOCIN));
-NumBytes = sizeof(TOCIN);
-ExtHeader = TocIn.HeadLevel&HIGH_ORDER_MASK;
-if (ExtHeader) {
- memcpy(&TOCControlWord, pulTOCIndex[i]+sizeof(TOCIN), sizeof(USHORT));
- NumBytes += sizeof(USHORT);
- if (TOCControlWord&PANEL_EXTENDEDPARENT) {
- fParent = TRUE;
- }
- if (TOCControlWord&PANEL_EXTENDED_X_Y) {
- NumBytes+=(sizeof(BYTE)+2*sizeof(USHORT));
- }
- if (TOCControlWord&PANEL_EXTENDED_CX_CY) {
- NumBytes+=(sizeof(BYTE)+2*sizeof(USHORT));
- }
- if (TOCControlWord&PANEL_EXTENDED_STYLE) {
- NumBytes += sizeof(USHORT);
- }
- if (TOCControlWord&PANEL_EXTENDED_GROUP) {
- NumBytes += sizeof(USHORT);
- }
- if (TOCControlWord&PANEL_EXTENDED_CTRLSINDEX)
- NumBytes += sizeof(USHORT);
-}
-NumBytes += TOCIn.NumCells*sizeof(BYTE);
-pszTitle = malloc(TOCIn.LengthEntry-NumBytes+1);
-memcpy(pszTitle, pulTOCIndex[i]+NumBytes, TOCIn.LengthEntry-NumBytes);
-pszTitle[TOCIn.LengthEntry-NumBytes] = '\0';
-
-If the table of contents entry is on disk, the following code fragment
-retrieves the title and status as a parent using the TOC Offset Table.
-
-TOCIN TocIn;
-USHORT NumBytes;
-BOOL fParent = FALSE;
-PSZ pszTitle;
-
-fseek(fpointer, pulTOCOffsetTable[i], SEEK_SET);
-fread(&TOCIn, sizeof(TOCIN), 1, fpointer(TOCIN));
-NumBytes = sizeof(TOCIN);
-ExtHeader = TocIn.HeadLevel&HIGH_ORDER_MASK;
-if (ExtHeader) {
- fread(&TOCControlWord, sizeof(USHORT), 1, fpointer);
- NumBytes += sizeof(USHORT);
- if (TOCControlWord&PANEL_EXTENDEDPARENT) {
- fParent = TRUE;
- }
- if (TOCControlWord&PANEL_EXTENDED_X_Y) {
- fseek(fpointer, sizeof(BYTE)+2*sizeof(USHORT), SEEK_CUR);
- NumBytes+=(sizeof(BYTE)+2*sizeof(USHORT));
- }
- if (TOCControlWord&PANEL_EXTENDED_CX_CY) {
- fseek(fpointer, sizeof(BYTE)+2*sizeof(USHORT), SEEK_CUR);
- NumBytes+=(sizeof(BYTE)+2*sizeof(USHORT));
- }
- if (TOCControlWord&PANEL_EXTENDED_STYLE) {
- fseek(fpointer, sizeof(USHORT), SEEK_CUR);
- NumBytes += sizeof(USHORT);
- }
- if (TOCControlWord&PANEL_EXTENDED_GROUP) {
- fseek(fpointer, sizeof(USHORT), SEEK_CUR);
- NumBytes += sizeof(USHORT);
- }
- if (TOCControlWord&PANEL_EXTENDED_CTRLSINDEX) {
- fseek(fpointer, sizeof(USHORT), SEEK_CUR);
- NumBytes += sizeof(USHORT);
- }
-}
-NumBytes += TOCIn.NumCells*sizeof(BYTE);
-fseek(fpointer, TOCIn.NumCells*sizeof(BYTE), SEEK_CUR);
-pszTitle = malloc(TOCIn.LengthEntry-NumBytes+1);
-fread(pszTitle, TOCIn.LengthEntry-NumBytes, SEEK_SET);
-pszTitle[TOCIn.LengthEntry-NumBytes] = '\0';
-
-IMPORTANT: The title is not null terminated. We had to explicitly
- add a null to the end of the title.
-
-The TOCIN structure and TOCControlWord provide a lot more information
-than we are using in the above fragment. One important piece of
-information is the headlevel. This is available in the HeadLevel
-field of the TOCIN structure. To actually get at the headlevel,
-you must OR the HeadLevel field with LOW_ORDER_MASK. The result is
-a byte indicating the head level (1-6). Most of the other information
-in the table of contents is not really usable until a panel is displayed.
-When we are displaying a panel, we will reaccess the table of contents
-entry to get the pertinent information.
-
-
-Displaying a Panel
-==================
-The next step is displaying a panel. All that is necessary to display
-a panel is an index to a table of contents entry. We will use this
-index to get all the information about the panel. Table of contents
-indexes are obtained from various places including the index table,
-the panel number table, the panel name table, and the search table.
-In our viewer, we obtain the table of contents index determine which
-table of contents entry the use selected. Remember that we did not save
-the title entries of the table of contents. The reason we did not is
-because all we need is an index to the table of contents entry. The
-title is not necessary for access.
-
-The first step is to get the TOCIN structure from memory or from the
-file. This is performed in the same manner as the above code
-fragments. Once we have the TOCIN structure, we can detect the presence
-of an extended table of contents header (hereafter referred to as the
-control word). To detect the presence of a control word, we OR the
-HeadLevel value with the HIGH_ORDER_MASK. If the resulting value
-is not zero, there is a control word present. The control word
-is defined as a USHORT. By ORing the TOCControlWord with various
-constants defined in the header file, we can determine information
-about the panel including location, size, group, etc. The following
-constants are used to find that information.
-
-PANEL_EXTENDED_VIEWPORT
-PANEL_EXTENDED_NOSEARCH - Entry should not be searched
-PANEL_EXTENDED_NOPRINT - Entry should not be printed
-PANEL_EXTENDED_AUTO
-PANEL_EXTENDED_CHILD - Entry is a child
-PANEL_EXTENDED_CLEAR
-PANEL_EXTENDED_DEPENDENT
-PANEL_EXTENDED_PARENT - Entry is a parent
-PANEL_EXTENDED_TUTORIAL
-
-PANEL_EXTENDED_X_Y - lower left location of panel
-Read in additional byte,word,word
-PANEL_EXTENDED_CX_CY - size of panel
-Read in additional byte,word,word
-PANEL_EXTENDED_STYLE - style of window
-Read in additional word
-PANEL_EXTENDED_GROUP - group number
-Read in additional word
-PANEL_EXTENDED_CTRLSINDEX - control group index
-Read in additonal word
-
-To obtain a better understanding of things like groups and control
-group indexes, please consult the Information Presentation Facility
-Guide and Reference.
-
-The last five constants indicate that additional information needs
-to be read after the control word. You will note that in the
-above code fragments for reading the title, we had to process these
-values and skip bytes where appropriate. Later, in the code
-fragments to retrieve control word information, we will show you how
-to get these extra values.
-
-The other bit of information available in the HeadLevel field is,
-suprisingly, the head level! We can obtain the headlevel by ORing
-the value in HeadLevel with LOW_ORDER_MASK.
-
-The following code fragment reads in the extended header informatiom
-from memory and sets some variables based on the above constants.
-It also obtains the head level. Note that for your particular
-application, you might not need all of this information.
-
-/* INSERT CODE FRAGMENT THAT USES MEMCPY TO GET TOC AND PANEL INFO */
-
-If you are reading the table of contents from the file instead of
-memory, use the following code fragment.
-
-TOCIN TocIn;
-USHORT NumBytes;
-BOOL fParent = FALSE;
-PSZ pszTitle;
-
-fseek(fpointer, pulTOCOffsetTable[i], SEEK_SET);
-fread(&TOCIn, sizeof(TOCIN), 1, fpointer(TOCIN));
-HeadLevel = TOCIn.HeadLevel&LOW_ORDER_MASK;
-ExtHeader = TocIn.HeadLevel&HIGH_ORDER_MASK;
-if (ExtHeader) {
- fread(&TOCControlWord, sizeof(USHORT), 1, fpointer);
- if (TOCControlWord&PANEL_EXTENDED_X_Y) {
- fread(&bxyUnits, sizeof(BYTE), 1, fpointer);
- fread(&usx, sizeof(USHORT), 1, fpointer);
- fread(&usy, sizeof(USHORT), 1, fpointer);
- }
- if (TOCControlWord&PANEL_EXTENDED_CX_CY) {
- fread(&bcxcyUnits, sizeof(BYTE), 1, fpointer);
- fread(&uscx, sizeof(USHORT), 1, fpointer);
- fread(&uscy, sizeof(USHORT), 1, fpointer);
- }
- if (TOCControlWord&PANEL_EXTENDED_STYLE)
- fread(&usStyle, sizeof(USHORT), 1, fpointer);
- if (TOCControlWord&PANEL_EXTENDED_GROUP)
- fread(&usGroupNumber, sizeof(USHORT), 1, fpointer);
- if (TOCControlWord&PANEL_EXTENDED_CTRLSINDEX)
- fread(&usControlGroupIndex, sizeof(USHORT), 1, fpointer);
-}
-
-The information from the table of contents header is generally only
-used to decide how the window that the help is in will be displayed.
-
-You can use it to position your window and to decide whether it has
-a border, minimize or mazimize buttons, etc.
-Once you have all of the display information from the table of contents,
-you can begin actually getting the information that is in the panel.
-Don't forget to display the title of the panel. We obtained it
-again in the above code fragments.
-
-A panel consists of one or more cells that contain formatting information
-and the text of the panel. In most cases, panels have more than one
-cell, so you cannot make the assumption that panels have once cell.
-The number of cells in a panel can be found from the NumCells field
-in the TOCIN structure.
-
-After reading all the extended header information and the title in the
-above samples, you will notice that we saved a value called
-pusBeginCell. This is a pointer to the place in the table of contents
-where the list of cells begins. These cell values actually index into
-the Cell Offset Table. Using the Cell Offset Table we can get the file
-offsets of the individual cells and display the information in them.
-
-The offsets in the COT are only used to retrieve the actual cell.
-In and of themselves, they provide no additional information. For this
-reason, they will only be used as a part of a code fragment to retrieve
-the actual cell.
-
-In retrieving the cell, the first step is to retrieve the cell header.
-The cell offset points to this header. Once we have the header, we
-can get the information to display the cell.
-
-The following code fragment loops through all cells in table of contents
-entry i, and reads in the cell headers. The dots indicate
-where you would actually process the information in the cell, which we
-will do later.
-
-INT j;
-USHORT usCOTIndex;
-CELL Cell;
-
-for (j=0; j<=TOCIn.NumCells; j++)
-/* If the table of contents is in memory, use */
- memcpy(&usCOTIndex, pusBeginCell, sizeof(USHORT));
-/* If the table of contents is on disk, use */
- fseek(fpointer, pusBeginCell, SEEK_SET);
- fread(&usCOTIndex, sizeof(USHORT),1,fpointer);
-/* What follows is the same for both cases */
- fseek(fpointer, COT[usCOTIndex], SEEK_SET);
- fread(&Cell, sizeof(CELL),1,fpointer);
- .
- .
- .
-}
-
-The cell information allows us to actually display the text itself.
-
-In the cell header, we have information about the CVT and the CDI.
-These two arrays give us the actual formatting information. The CDI
-contains formatting information and words. The words are represented
-as indexes into the CVT. The CVT elements are indexes into the
-vocabulary (CLVT). To use the CVT and CDI, we will read them into
-memory and process the CVT byte by byte. The following code fragment
-reads the CVT and the CDI into memory. Note that after reading
-the cell header from the file, we are pointing at the beginning of the
-CDI.
-
-PBYTE CDI;
-PUSHORT CVT;
-
- CDI = malloc(Cell.CDISize);
- rc=fread(CDI,Cell.CDISize,1,fpointer);
- rc=fseek(fpointer,Cell.CVTOffset, SEEK_SET);
- CVT = malloc(Cell.CVTSize*2);
- rc=fread(CVT, Cell.CVTSize*2,1,fpointer);
-
-Even though the CVT is right after the CDI in the header, we cannot
-assume that after reading the CDI we are pointing at the CVT. We
-must fseek to the CVTOffset.
-
-Now we want to read the CDI byte by byte and process each item.
-The CDI values are either FA thru FF or they are a number which
-indexes into the CVT which then indexes into the vocabulary.
-Whenever the CDI value is an FF, we need to read additional info.
-This additional info is formatting information, font changes, links,
-etc. The FF escape code values are documented in appendix A.
-The following code fragment does some very basic formatting of a cell.
-Figure 5 provides the values for each of the BYTE_* values.
-
-INT m;
-INT l;
-CHAR String[255];
-BOOL Together = FALSE;
-
-for (m=0;m<Cell.CDISize;m++ ) {
- switch (CDI[m]) {
- /* The value indicates a new paragraph */
- case BYTE_PARA :
- printf("\n ");
- break;
- /* The value indicates that the text following should be centered. */
- /* Center all text until a BYTE_NEWLINE is encountered */
- case BYTE_CENTRE :
- printf("Center\n");
- break;
- /* Autoblanks are used to indicate when there should be no spaces */
- /* between words. When you encounter an autoblank, all words */
- /* following should be printed without spaces until another autoblank */
- /* is encountered. */
- case BYTE_AUTOBLANK :
- if (Together)
- Together = FALSE;
- else
- Together = TRUE;
- break;
- /* The value indicates to print a new line */
- case BYTE_NEWLINE :
- printf("\n");
- break;
- /* The value indicates a space */
- case BYTE_BLANK :
- printf(" ");
- break;
- /* The value is an escape code. We should do some processing within */
- /* This statement to handle the various cases documented in */
- /* Appendix A */
- case BYTE_ESC :
- break;
- /* Not sure */
- case WILD_CHAR :
- break;
- /* Not sure */
- case ESC_CHAR :
- break;
- /* It is a word. Index into the CVT to get the vocabulary offset */
- /* And print the word */
- default:
- l = pulVocabIndex[CVT[CDI[m]]]+1;
- for (k=0;k<(pchVocab[pulVocabIndex[CVT[CDI[m]]]]-1) ;k++,l++ )
- String[k] = pchVocab[l];
- /* Don't forget to null terminate the word. */
- String[k] = '\0';
- if (Together)
- printf("%s",String);
- else
- printf("%s ",String);
-
- break;
- } /* endswitch */
-} /* endfor */
-
-So that is the basics. You should now be able to display a cell.
-
-Accessing other information within the INF file
------------------------------------------------
-Index table (index) - synonym table
-Index command table (icmd)
-Panel table (context sensitive help)
-Panel name table (link)
-
-Database names
-Fonts
-Country / Grammar
-Bitmaps (should be interesting due to different compression)
-Strings
-Control
-Super Search Table (aka FTS or Full Text Search)
-Child pages
-
-
-Searching
-=========
-If you just want to search an INF file, you will still have to read in
-the vocabulary and the table of contents. You search the vocabulary
-for a word, and then get the index of that word. This index can be
-used to index into the Super Search Table which allows you to
-determine which panels contain that word. What a pain!
-
- ---------o0O0o---------
-
+ + Information on reading the INF file format + ========================================== + +Author: unknown +Date: unknown + + +This article is intended to provide the reader with enough information +to read and search the HLP/INF file format. Support is not provided +for constructing your own INF files. + +The INF and HLP file format are exactly the same except for the +switching of two bytes in the header. Therefore all the information in +this article applies to both HLP and INF files. The difference between +the two will be explained later. I will, however, use the term "INF +format" to distinguish between OS/2 HLP files and Windows HLP files. + +This article will be divided into three main parts. First there will +be an overview of the file format. Second there will be information on +accessing parts of this format, including code samples. Third will be +information on searching the INF format. + +Note that to understand a lot of the concepts in displaying panels, +an understanding of the IPF Guide and Reference is necessary. This +will give an understanding of the ways in which panels can be modified +in terms of sizes, styles, etc. + + +Overview +======== + + [This is where I will put Stan's document] + +Accessing Information in the INF/HLP file +----------------------------------------- +The next part of this article is organized as if you are writing your +own INF/HLP viewer. It will provide explanations on how to do the +following things: + +1. Read in header information. This will allow you to display the + title and access the rest of the information in the panel. + +2. Read in and index the vocabulary. + +3. Read in the Cell Offset Table. This will be used later to display + panels. + +4. Read in the table of contents. Explanations will be given for two + methods of accessing the table of contents. The first is from + memory. This method is useful if you are reading the entire table + of contents at once to display it, or if your application will + provide primary access to panels through the table of contents. The + second method of accessing table of contents entries is directly + from the file. This method is useful for linking and for displaying + a panel initially when a file is opened. In OS/2, VIEW uses the + first method whereas displaying help for an application uses the + second method. + +5. Display the titles of all panels in the file. Titles will not be + stored because access to the table of contents is provided by + index, not by title. There is a lot of extra information in the + table of contents entries that will not be used until a cell is + actually displayed. + +6. Display a panel. This will be the most involved explanation. + Displaying a panel actually requires retrieving a lot of + information from the table of contents and then reading and + formatting the data within the panel. + +Note that this makes some basic assumptions that you are going to use +the file in a similar manner as OS/2s VIEW program and Help Manager. + + +Headers +======= +The first step in accessing information in the file is to read in the +header. Figures 1 and 2 show the structures used to acccess the +regular and extended headers. The extended header is not in every +file. It can be detected by checking the ExtHeaderOffset in the +DOCHEADER structure. If the ExtHeaderOffset is greater than 0, then it +is the file offset of the extended header. The following code fragment +opens the file and reads the DOCHEADER and the EXTHEADER if necessary. + +DOCHEADER DocHeader; +EXTHEADER ExtHeader; +FILE* fpointer; +CHAR* FileName; + +fpointer = fopen(FileName,"rb"); +fread(&DocHeader,sizeof(DOCHEADER),1,fpointer); +if (DocHeader.ExtHeaderOffset > 0) { + fseek(fpointer, DocHeader.ExtHeaderOffset, SEEK_SET); + fread(&ExtHeader,sizeof(EXTHEADER),1,fpointer); +} + +The DOCHEADER contains all of the information needed to access data +within the file. At this point, though, there are only a couple +fields we are concerned about. The first is the FileCTRLWord. This +field indicates the type of file. If it is 0x01505348 it is an INF file; +If it is 0x10505348, it is a HLP file. The other field of use right now +is the Title; this is simply a null-terminated string containing +the title of the document. One interesting note is that although +the title for a HLP file is normally specified in an application, +there still is a title in the HLP file if the writer specified +a :title. tag. + + +Vocabulary +========== +Once the DOCHEADER is obtained, the next step is to read the vocabulary. +All references to the vocabulary in the INF/HLP file are made via an +index value. This index, however, is not in the file so it must be +built. The following code fragment reads in the vocabulary and builds +an index to it. + +PULONG pulVocabIndex; +PCHAR pchVocab; +ULONG ulVocabPointer; +INT i; + +pchVocab = malloc(DocHeader.CLVTSize); +pulVocabIndex = malloc(DocHeader.CLVTNumWords*(sizeof(ULONG)); + +fseek(fpointer, DocHeader.CLVTOffset,SEEK_SET); +fread(pchVocab, DocHeader.CLVTSize, 1, fpointer); + +ulVocabPointer = 0; +for (i=0;i< DocHeader.CLVTNumWords ;i++ ) { + pulVocabIndex[i] = ulVocabPointer; + ulVocabPointer += pchVocab[ulVocabPointer]; +} /* endfor */ + +Remember that when referencing the vocabulary, the first byte contains the +length of the word, including the first byte. Here is the result of the +above code sample with a vocabulary of {you, can, develop}. + +Example: +-------- +pchVocab -> 4can8develop4you + │ │ │ + │ └───┐ ┌┘ + └─────┐ │ │ +pulVocabIndex -> {0,4,12} + +Given any index into the vocabulary, you can then reference the +appropriate word. + + +Cell Offset Table +================= +The Cell Offset Table will be read next. It will be used later to +get the file offsets of the cells within each panel. The information +needed to obtain the Cell Offset Table is contained in the DOCHEADER. +The pertinent fields are NumCell and COTOffset. The following code +fragment retrieves the Cell Offset Table from the file. + +PULONG pulCOT; + +pulCOT = malloc(DocHeader.NumCell*sizeof(ULONG)); +fseek(fpointer, DocHeader.COTOffset, SEEK_SET); +fread(pulCOT, DocHeader.NumCell*sizeof(ULONG), 1, fpointer); + + +Table Of Contents +================= +The next step is to read the table of contents into memory. +The DOCHEADER contains all the values necessary to read the table of +contents. TOCOffset contains the file offset of the table of contents +and TOCSize contains the size. The table of contents is read in a +similar manner to the vocabulary; that is, it is read into memory +and then indexed. The following code fragments reads the table +of contents into memory. + +PULONG pulTOCIndex; +PBYTE pbTOC; +ULONG ulTOCPointer; +INT i; + +pbTOC = malloc(DocHeader.TOCSize); +pulTOCIndex = malloc(DocHeader.NumTOCEntry*(sizeof(ULONG)); + +fseek(fpointer, DocHeader.TOCOffset,SEEK_SET); +fread(pbTOC, DocHeader.TOCSize, 1, fpointer); + +ulTOCPointer = pbTOC; +for (i=0;i< DocHeader.NumTOCEntry ;i++ ) { + pulTOCIndex[i] = ulTOCPointer; + ulTOCPointer += (BYTE) *pvTOC; +} /* endfor */ + +Each entry in the TOC index is an address of a TOC entry. Once the TOC +is in memory, individual TOC items can be referenced. Note that this +is not the only way to reference the TOC. There is also a TOC Ofset +Table which provides file offsets to individual TOC items. This is used +when you need to reference a panel individually by its TOC index. +This is true when linking and when opening a HLP or INF file without +display the table of contents first. The following code fragment +retrieves the TOC Offset Table. + +PULONG pulTOCOffsetTable; + +pulTOCOffsetTable = malloc(DocHeader.NumTOCEntry*sizeof(ULONG)); + +fseek(fpointer, DocHeader.OfsTiTICOfsTable,SEEK_SET); +fread(pulTOCOffsetTable, DocHeader.NumTOCEntry*sizeof(ULONG), 1, fpointer); + +Once you have access to a table of contents entry, you must then read +in the data contained there. This is not very straightforward due +to the fact that TOC entries can very greatly in length. At this point, +though, the important thing to read from the TOC entries are the titles. +You will probably not want to use the header information until you need +to display a panel. The following code fragment just reads the title +given that the table of contents is in memory and the entry we want +to access is i. It also checks the the extended header (if it exists) +to determine whether or not the entry is a parent. This will allow +you to display some sort of indicator that the entry can be expanded +to display its children, similar to the way the help manager does. + +TOCIN TocIn; +USHORT NumBytes; +BOOL fParent = FALSE; +PSZ pszTitle; +USHORT TOCControlWord; + +memcpy(&TOCIn, pulTOCIndex[i], sizeof(TOCIN)); +NumBytes = sizeof(TOCIN); +ExtHeader = TocIn.HeadLevel&HIGH_ORDER_MASK; +if (ExtHeader) { + memcpy(&TOCControlWord, pulTOCIndex[i]+sizeof(TOCIN), sizeof(USHORT)); + NumBytes += sizeof(USHORT); + if (TOCControlWord&PANEL_EXTENDEDPARENT) { + fParent = TRUE; + } + if (TOCControlWord&PANEL_EXTENDED_X_Y) { + NumBytes+=(sizeof(BYTE)+2*sizeof(USHORT)); + } + if (TOCControlWord&PANEL_EXTENDED_CX_CY) { + NumBytes+=(sizeof(BYTE)+2*sizeof(USHORT)); + } + if (TOCControlWord&PANEL_EXTENDED_STYLE) { + NumBytes += sizeof(USHORT); + } + if (TOCControlWord&PANEL_EXTENDED_GROUP) { + NumBytes += sizeof(USHORT); + } + if (TOCControlWord&PANEL_EXTENDED_CTRLSINDEX) + NumBytes += sizeof(USHORT); +} +NumBytes += TOCIn.NumCells*sizeof(BYTE); +pszTitle = malloc(TOCIn.LengthEntry-NumBytes+1); +memcpy(pszTitle, pulTOCIndex[i]+NumBytes, TOCIn.LengthEntry-NumBytes); +pszTitle[TOCIn.LengthEntry-NumBytes] = '\0'; + +If the table of contents entry is on disk, the following code fragment +retrieves the title and status as a parent using the TOC Offset Table. + +TOCIN TocIn; +USHORT NumBytes; +BOOL fParent = FALSE; +PSZ pszTitle; + +fseek(fpointer, pulTOCOffsetTable[i], SEEK_SET); +fread(&TOCIn, sizeof(TOCIN), 1, fpointer(TOCIN)); +NumBytes = sizeof(TOCIN); +ExtHeader = TocIn.HeadLevel&HIGH_ORDER_MASK; +if (ExtHeader) { + fread(&TOCControlWord, sizeof(USHORT), 1, fpointer); + NumBytes += sizeof(USHORT); + if (TOCControlWord&PANEL_EXTENDEDPARENT) { + fParent = TRUE; + } + if (TOCControlWord&PANEL_EXTENDED_X_Y) { + fseek(fpointer, sizeof(BYTE)+2*sizeof(USHORT), SEEK_CUR); + NumBytes+=(sizeof(BYTE)+2*sizeof(USHORT)); + } + if (TOCControlWord&PANEL_EXTENDED_CX_CY) { + fseek(fpointer, sizeof(BYTE)+2*sizeof(USHORT), SEEK_CUR); + NumBytes+=(sizeof(BYTE)+2*sizeof(USHORT)); + } + if (TOCControlWord&PANEL_EXTENDED_STYLE) { + fseek(fpointer, sizeof(USHORT), SEEK_CUR); + NumBytes += sizeof(USHORT); + } + if (TOCControlWord&PANEL_EXTENDED_GROUP) { + fseek(fpointer, sizeof(USHORT), SEEK_CUR); + NumBytes += sizeof(USHORT); + } + if (TOCControlWord&PANEL_EXTENDED_CTRLSINDEX) { + fseek(fpointer, sizeof(USHORT), SEEK_CUR); + NumBytes += sizeof(USHORT); + } +} +NumBytes += TOCIn.NumCells*sizeof(BYTE); +fseek(fpointer, TOCIn.NumCells*sizeof(BYTE), SEEK_CUR); +pszTitle = malloc(TOCIn.LengthEntry-NumBytes+1); +fread(pszTitle, TOCIn.LengthEntry-NumBytes, SEEK_SET); +pszTitle[TOCIn.LengthEntry-NumBytes] = '\0'; + +IMPORTANT: The title is not null terminated. We had to explicitly + add a null to the end of the title. + +The TOCIN structure and TOCControlWord provide a lot more information +than we are using in the above fragment. One important piece of +information is the headlevel. This is available in the HeadLevel +field of the TOCIN structure. To actually get at the headlevel, +you must OR the HeadLevel field with LOW_ORDER_MASK. The result is +a byte indicating the head level (1-6). Most of the other information +in the table of contents is not really usable until a panel is displayed. +When we are displaying a panel, we will reaccess the table of contents +entry to get the pertinent information. + + +Displaying a Panel +================== +The next step is displaying a panel. All that is necessary to display +a panel is an index to a table of contents entry. We will use this +index to get all the information about the panel. Table of contents +indexes are obtained from various places including the index table, +the panel number table, the panel name table, and the search table. +In our viewer, we obtain the table of contents index determine which +table of contents entry the use selected. Remember that we did not save +the title entries of the table of contents. The reason we did not is +because all we need is an index to the table of contents entry. The +title is not necessary for access. + +The first step is to get the TOCIN structure from memory or from the +file. This is performed in the same manner as the above code +fragments. Once we have the TOCIN structure, we can detect the presence +of an extended table of contents header (hereafter referred to as the +control word). To detect the presence of a control word, we OR the +HeadLevel value with the HIGH_ORDER_MASK. If the resulting value +is not zero, there is a control word present. The control word +is defined as a USHORT. By ORing the TOCControlWord with various +constants defined in the header file, we can determine information +about the panel including location, size, group, etc. The following +constants are used to find that information. + +PANEL_EXTENDED_VIEWPORT +PANEL_EXTENDED_NOSEARCH - Entry should not be searched +PANEL_EXTENDED_NOPRINT - Entry should not be printed +PANEL_EXTENDED_AUTO +PANEL_EXTENDED_CHILD - Entry is a child +PANEL_EXTENDED_CLEAR +PANEL_EXTENDED_DEPENDENT +PANEL_EXTENDED_PARENT - Entry is a parent +PANEL_EXTENDED_TUTORIAL + +PANEL_EXTENDED_X_Y - lower left location of panel +Read in additional byte,word,word +PANEL_EXTENDED_CX_CY - size of panel +Read in additional byte,word,word +PANEL_EXTENDED_STYLE - style of window +Read in additional word +PANEL_EXTENDED_GROUP - group number +Read in additional word +PANEL_EXTENDED_CTRLSINDEX - control group index +Read in additonal word + +To obtain a better understanding of things like groups and control +group indexes, please consult the Information Presentation Facility +Guide and Reference. + +The last five constants indicate that additional information needs +to be read after the control word. You will note that in the +above code fragments for reading the title, we had to process these +values and skip bytes where appropriate. Later, in the code +fragments to retrieve control word information, we will show you how +to get these extra values. + +The other bit of information available in the HeadLevel field is, +suprisingly, the head level! We can obtain the headlevel by ORing +the value in HeadLevel with LOW_ORDER_MASK. + +The following code fragment reads in the extended header informatiom +from memory and sets some variables based on the above constants. +It also obtains the head level. Note that for your particular +application, you might not need all of this information. + +/* INSERT CODE FRAGMENT THAT USES MEMCPY TO GET TOC AND PANEL INFO */ + +If you are reading the table of contents from the file instead of +memory, use the following code fragment. + +TOCIN TocIn; +USHORT NumBytes; +BOOL fParent = FALSE; +PSZ pszTitle; + +fseek(fpointer, pulTOCOffsetTable[i], SEEK_SET); +fread(&TOCIn, sizeof(TOCIN), 1, fpointer(TOCIN)); +HeadLevel = TOCIn.HeadLevel&LOW_ORDER_MASK; +ExtHeader = TocIn.HeadLevel&HIGH_ORDER_MASK; +if (ExtHeader) { + fread(&TOCControlWord, sizeof(USHORT), 1, fpointer); + if (TOCControlWord&PANEL_EXTENDED_X_Y) { + fread(&bxyUnits, sizeof(BYTE), 1, fpointer); + fread(&usx, sizeof(USHORT), 1, fpointer); + fread(&usy, sizeof(USHORT), 1, fpointer); + } + if (TOCControlWord&PANEL_EXTENDED_CX_CY) { + fread(&bcxcyUnits, sizeof(BYTE), 1, fpointer); + fread(&uscx, sizeof(USHORT), 1, fpointer); + fread(&uscy, sizeof(USHORT), 1, fpointer); + } + if (TOCControlWord&PANEL_EXTENDED_STYLE) + fread(&usStyle, sizeof(USHORT), 1, fpointer); + if (TOCControlWord&PANEL_EXTENDED_GROUP) + fread(&usGroupNumber, sizeof(USHORT), 1, fpointer); + if (TOCControlWord&PANEL_EXTENDED_CTRLSINDEX) + fread(&usControlGroupIndex, sizeof(USHORT), 1, fpointer); +} + +The information from the table of contents header is generally only +used to decide how the window that the help is in will be displayed. + +You can use it to position your window and to decide whether it has +a border, minimize or mazimize buttons, etc. +Once you have all of the display information from the table of contents, +you can begin actually getting the information that is in the panel. +Don't forget to display the title of the panel. We obtained it +again in the above code fragments. + +A panel consists of one or more cells that contain formatting information +and the text of the panel. In most cases, panels have more than one +cell, so you cannot make the assumption that panels have once cell. +The number of cells in a panel can be found from the NumCells field +in the TOCIN structure. + +After reading all the extended header information and the title in the +above samples, you will notice that we saved a value called +pusBeginCell. This is a pointer to the place in the table of contents +where the list of cells begins. These cell values actually index into +the Cell Offset Table. Using the Cell Offset Table we can get the file +offsets of the individual cells and display the information in them. + +The offsets in the COT are only used to retrieve the actual cell. +In and of themselves, they provide no additional information. For this +reason, they will only be used as a part of a code fragment to retrieve +the actual cell. + +In retrieving the cell, the first step is to retrieve the cell header. +The cell offset points to this header. Once we have the header, we +can get the information to display the cell. + +The following code fragment loops through all cells in table of contents +entry i, and reads in the cell headers. The dots indicate +where you would actually process the information in the cell, which we +will do later. + +INT j; +USHORT usCOTIndex; +CELL Cell; + +for (j=0; j<=TOCIn.NumCells; j++) +/* If the table of contents is in memory, use */ + memcpy(&usCOTIndex, pusBeginCell, sizeof(USHORT)); +/* If the table of contents is on disk, use */ + fseek(fpointer, pusBeginCell, SEEK_SET); + fread(&usCOTIndex, sizeof(USHORT),1,fpointer); +/* What follows is the same for both cases */ + fseek(fpointer, COT[usCOTIndex], SEEK_SET); + fread(&Cell, sizeof(CELL),1,fpointer); + . + . + . +} + +The cell information allows us to actually display the text itself. + +In the cell header, we have information about the CVT and the CDI. +These two arrays give us the actual formatting information. The CDI +contains formatting information and words. The words are represented +as indexes into the CVT. The CVT elements are indexes into the +vocabulary (CLVT). To use the CVT and CDI, we will read them into +memory and process the CVT byte by byte. The following code fragment +reads the CVT and the CDI into memory. Note that after reading +the cell header from the file, we are pointing at the beginning of the +CDI. + +PBYTE CDI; +PUSHORT CVT; + + CDI = malloc(Cell.CDISize); + rc=fread(CDI,Cell.CDISize,1,fpointer); + rc=fseek(fpointer,Cell.CVTOffset, SEEK_SET); + CVT = malloc(Cell.CVTSize*2); + rc=fread(CVT, Cell.CVTSize*2,1,fpointer); + +Even though the CVT is right after the CDI in the header, we cannot +assume that after reading the CDI we are pointing at the CVT. We +must fseek to the CVTOffset. + +Now we want to read the CDI byte by byte and process each item. +The CDI values are either FA thru FF or they are a number which +indexes into the CVT which then indexes into the vocabulary. +Whenever the CDI value is an FF, we need to read additional info. +This additional info is formatting information, font changes, links, +etc. The FF escape code values are documented in appendix A. +The following code fragment does some very basic formatting of a cell. +Figure 5 provides the values for each of the BYTE_* values. + +INT m; +INT l; +CHAR String[255]; +BOOL Together = FALSE; + +for (m=0;m<Cell.CDISize;m++ ) { + switch (CDI[m]) { + /* The value indicates a new paragraph */ + case BYTE_PARA : + printf("\n "); + break; + /* The value indicates that the text following should be centered. */ + /* Center all text until a BYTE_NEWLINE is encountered */ + case BYTE_CENTRE : + printf("Center\n"); + break; + /* Autoblanks are used to indicate when there should be no spaces */ + /* between words. When you encounter an autoblank, all words */ + /* following should be printed without spaces until another autoblank */ + /* is encountered. */ + case BYTE_AUTOBLANK : + if (Together) + Together = FALSE; + else + Together = TRUE; + break; + /* The value indicates to print a new line */ + case BYTE_NEWLINE : + printf("\n"); + break; + /* The value indicates a space */ + case BYTE_BLANK : + printf(" "); + break; + /* The value is an escape code. We should do some processing within */ + /* This statement to handle the various cases documented in */ + /* Appendix A */ + case BYTE_ESC : + break; + /* Not sure */ + case WILD_CHAR : + break; + /* Not sure */ + case ESC_CHAR : + break; + /* It is a word. Index into the CVT to get the vocabulary offset */ + /* And print the word */ + default: + l = pulVocabIndex[CVT[CDI[m]]]+1; + for (k=0;k<(pchVocab[pulVocabIndex[CVT[CDI[m]]]]-1) ;k++,l++ ) + String[k] = pchVocab[l]; + /* Don't forget to null terminate the word. */ + String[k] = '\0'; + if (Together) + printf("%s",String); + else + printf("%s ",String); + + break; + } /* endswitch */ +} /* endfor */ + +So that is the basics. You should now be able to display a cell. + +Accessing other information within the INF file +----------------------------------------------- +Index table (index) - synonym table +Index command table (icmd) +Panel table (context sensitive help) +Panel name table (link) + +Database names +Fonts +Country / Grammar +Bitmaps (should be interesting due to different compression) +Strings +Control +Super Search Table (aka FTS or Full Text Search) +Child pages + + +Searching +========= +If you just want to search an INF file, you will still have to read in +the vocabulary and the table of contents. You search the vocabulary +for a word, and then get the index of that word. This index can be +used to index into the Super Search Table which allows you to +determine which panels contain that word. What a pain! + + ---------o0O0o--------- + diff --git a/docview/docs/ascii-ibm-extended-character-set_files/script-bin.js b/docview/docs/ascii-ibm-extended-character-set_files/script-bin.js index f5c95601..ccdce239 100644 --- a/docview/docs/ascii-ibm-extended-character-set_files/script-bin.js +++ b/docview/docs/ascii-ibm-extended-character-set_files/script-bin.js @@ -1,587 +1,587 @@ - // fullwin1.js
-
- // CONSTRUCTOR FUNCTION TO CREATE FULLWIN OBJECT
- function _fullWin_object ( win_url, win_name, win_ref, win_features )
- {
- this.win_url = win_url;
- this.win_name = win_name;
- this.win_ref = win_ref;
- this.win_features = win_features;
- }
-
- // DECLARE SCRIPTS ARRAY
- var _fullWin = new Array;
-
- function _fullWindow(winURL) {
-
- var winName = replaceBadCharacters(winURL);
-
- var linkID = "";
- if (_fullWindow.arguments.length > 1 && _fullWindow.arguments[1].length > 0) {
- linkID = _fullWindow.arguments[1];
- winName += linkID;
- }
-
- // MAKE ROBUST FUNCTION - TEST ARGUMENTS FIRST
- if (_fullWindow.arguments.length < 1) {
- alert ( "\nPage Scripting Error!\nInvalid number of arguments passed to 'full_window' function.\n" );
- return(false);
- } else if ( typeof ( winName ) != "string" || winName.length < 2) {
- alert ( "\nPage Scripting Error!\nInvalid 'targetName' string passed to 'full_window' function.\n" );
- return (false);
- }
-
- var win_num = _fullWin.length;
- var found = false;
-
- for (var num=0; num<_fullWin.length; num++) {
-
- if ( winURL==_fullWin[num].win_url && winName==_fullWin[num].win_name) {
- win_num = num;
- found = true;
- break;
- }
- }
-
- if (!found) {
-
- _fullWin[win_num] = new _fullWin_object (
- winURL,
- winName,
- null,
- "" );
- }
-
- var fw = _fullWin[win_num];
-
- // IF FULL WINDOW IS ALREADY OPEN
- if (remoteWindowOpen(fw.win_ref)) {
-
- // BRING EXISTING WINDOW TO TOP
- fw.win_ref.focus ();
- return(remoteWindowOpen(fw.win_ref));
- }
-
- fw.win_features = full_window_features ();
-
- var win_ref = window.open(fw.win_url,fw.win_name,fw.win_features);
-
- fw.win_ref = win_ref;
-
- if (remoteWindowOpen(fw.win_ref)) {
- fw.win_ref.focus ();
- }
-
- var retCode = remoteWindowOpen(fw.win_ref);
-// alert(retCode);
- return(retCode);
- }
-
-
- function replaceBadCharacters(string) {
-
- // CONVERT STRING TO UPPER CASE
- string = string.toUpperCase();
-
- // REMOVE COMMON EXTENSION FROM END OF FILENAME
- string = string.replace(/.htm|.html$|.shtml|.asp/i,"");
-
- // REMOVE PROTOCOL FROM BEGINNING OF URL
-// string = string.replace(/^http:\/\/www.|http:\/\//i,"");
-
- // REMOVE ALL BAD CHARACTERS FROM REMAINING STRING
- string = string.replace(/\/|:|\+|-|\.|_| |=|#|%|\?|\&|,/ig,"");
-
- // REDUCE LENGTH OF STRING TO 12
- string = string.substr(string.length-12,12);
-
- return(string);
- }
-
-
- function full_window_features ()
- {
- var featuresList = "directories=yes";
-
- if ( navigator.userAgent.indexOf ( "Opera" ) > -1 ) {
- featuresList += ",top=0"; // doesn't WORK
- featuresList += ",left=0"; // doesn't WORK
- featuresList += ",height=" + screen.availHeight;
- featuresList += ",width=" + screen.availWidth;
- } else if ( navigator.userAgent.indexOf ( "Gecko" ) > -1 ) {
- featuresList += ",top=" + screen.availTop;
- featuresList += ",left=" + screen.availLeft;
- featuresList += ",height=" + ( screen.availHeight - 144 );
- featuresList += ",width=" + ( screen.availWidth - 7 );
- } else if ( document.all ) {
- featuresList += ",top=" + parseInt(screen.availTop,10);
- featuresList += ",left=" + parseInt(screen.availLeft,10);
- featuresList += ",height=" + screen.availHeight;
- featuresList += ",width=" + screen.availWidth;
- } else if ( document.layers ) {
- featuresList += ",top=" + screen.availTop;
- featuresList += ",left=" + screen.availLeft;
- featuresList += ",height=" + ( screen.availHeight - 157 );
- featuresList += ",width=" + ( screen.availWidth - 11 );
- } else if ( navigator.javaEnabled () ) {
- var toolkit = java.awt.Toolkit.getDefaultToolkit ();
- var screen_size = toolkit.getScreenSize ();
- featuresList += ",width=" + ( screen_size.width - 13 );
- featuresList += ",height=" + ( screen_size.height - 194 );
- } else if ( typeof ( screen ) == "object" ) {
- featuresList += ",top=" + screen.availTop;
- featuresList += ",left=" + screen.availLeft;
- featuresList += ",height=" + screen.availHeight;
- featuresList += ",width=" + screen.availWidth;
- }
-
- featuresList += ",location=1";
- featuresList += ",menubar=1";
- featuresList += ",scrollbars=1";
- featuresList += ",status=1";
- featuresList += ",toolbar=1";
- featuresList += ",resizable=1";
- featuresList += ",fullscreen=0";
-
- return(featuresList);
- }
-
-
- // CROSS PLATFORM, BOOLEAN, ERROR FREE TEST TO CHECK IF REMOTE WINDOW IS OPEN
- function remoteWindowOpen(window_reference) {
-
- if (window_reference !== null && window_reference.closed === false) {
- return(true);
- }
-
- return(false);
- }
-
-//=================================================================================
-
- function getMe() {
-
- var prot = '\x6D' + '\x61\x69\x6C' + '\x74\x6F';
- var addr = "\x48\x61d\x6Cey\x47\x40\x77eb\x2D\x77\x69se\x2D\x77\x69zard\x2E\x63\x6F\x6D";
-
- var htmstr = '<div> </div><div class="mailLink">';
- htmstr += 'E\x6D\x61il: <a href="' + prot + '\x3A' + addr + '">' + addr + '</a></div>';
-
- document.write(htmstr);
- }
-
-//=================================================================================
-
-// themes.js
-
-//=================================================================================
-
- var pathName = location.pathname.replace(/\\/g,"/");
-
- var siteIndex = false;
- if (pathName == "/" || pathName.match(/\/www\/index.html$/i)) {
- siteIndex = true;
- } else if (pathName == "/~webwisew/") {
- siteIndex = true;
- } else if (pathName == "/webmaste/www/") {
- siteIndex = true;
- }
-
- var imgObj = new Array();
- var imgArr = new Array();
- var imgArray = new Array (
- "line-horz-1.gif",
- "line-horz-2.gif",
- "line-horz-3.gif",
- "line-horz-4.gif",
- "theme-back.jpg",
- "deadlink-back.gif",
- "hoverlink-back.gif" );
-
-
- function preloadThemeImages(skinNo) {
-
- if (skinNo < 1 || skinNo > 6) {
- return;
- }
-
- var skinStr = "0" + skinNo;
- var preFix = (siteIndex) ? "" : "../";
- var imgPath = preFix + "images/skin-" + skinStr + "/";
-
- for (var count=0; count<imgArray.length; count++) {
- imgObj[count] = new Image();
- imgObj[count].src = imgPath + imgArray[count];
- }
- }
-
-
- var maxTheme = 6;
- var _startTheme = _endTheme = 0;
-
-
- function preloadOtherImages() {
-
- var skinStr, imgPath, arrayNum = -1;
-
- for (var skin=1; skin<7; skin++) {
-
- if (skin == _startTheme) {
- continue;
- }
-
- skinStr = "0" + skin;
- var preFix = (siteIndex) ? "" : "../";
- imgPath = preFix + "images/skin-" + skinStr + "/";
- if (siteIndex) {
- imgPath = imgPath.replace(/^..\//,"");
- }
-
- arrayNum ++;
- imgArr[arrayNum] = new Array();
- for (var count=0; count<imgArray.length; count++) {
- imgArr[arrayNum][count] = new Image();
- imgArr[arrayNum][count].src = imgPath + imgArray[count];
- }
-
- }
- }
-
-// window.onload=preloadOtherImages
-
-//=================================================================================
-
- var ssCookieName = "colorSelected";
- var ssCookieDays = 10;
- var ssCookieValue = 1;
-
- function setInitialStyles() {
-
- if (retroBrowser()) {
- return;
- }
-
- ssCookieValue = readCookie(ssCookieName);
- ssCookieValue = (ssCookieValue<1 || ssCookieValue>maxTheme) ? 1 : ssCookieValue;
- _startTheme = _endTheme = ssCookieValue;
-
- if (navigator.appName.match(/^Microsoft/i)) {
- preloadThemeImages(ssCookieValue);
- switchStyleSheetMicrosoft(ssCookieValue);
- } else if (navigator.appName.match(/^Netscape/i)) {
- preloadThemeImages(ssCookieValue);
- switchStyleSheetGecko(ssCookieValue);
- }
- }
-
-
- function changeScheme(toNum) {
-
- if (retroBrowser()) {
- return;
- }
-
- if (navigator.appName.match(/^Microsoft/i)) {
- preloadThemeImages(toNum);
- switchStyleSheetMicrosoft(toNum);
- } else if (navigator.appName.match(/^Netscape/i)) {
- preloadThemeImages(toNum);
- switchStyleSheetGecko(toNum);
- }
-
- ssCookieValue = toNum;
- createCookie(ssCookieName,ssCookieValue,ssCookieDays);
- _endTheme = toNum;
- }
-
-
- function retroBrowser () {
-
- if (document.layers) {
- return(true);
- } else if (navigator.userAgent.match(/Opera/ig)) {
- return(true);
- } else if (navigator.userAgent.match(/Safari/ig)) {
- return(true);
- }
-
- return(false);
- }
-
-
- function switchStyleSheetMicrosoft(toNum) {
-
- var preFix = (siteIndex) ? "" : "../";
-
- if (document.styleSheets[0].href !== null) {
- document.styleSheets[0].href = preFix + "css/www-theme-" + toNum + ".css";
- }
- }
-
-
- function switchStyleSheetGecko(toNum) {
-
- var linkTag, linkTitle = "skin" + toNum;
- var linksArray = document.getElementsByTagName("link");
-
- for(var linkNum=0; linkNum<linksArray.length; linkNum++) {
- linkTag = linksArray[linkNum];
- if(linkTag.getAttribute("rel").match(/^sty|^alt/i)) {
-
- if (linkTag.getAttribute("title") == linkTitle) {
- linkTag.disabled = false;
- } else if (linkTag.getAttribute("title")) {
- linkTag.disabled = true;
- }
- }
- }
- }
-
-
- function checkRadioButton() {
-
- var form;
-
- if (document.getElementById) {
- form = document.getElementById('colorSelect');
- form.colorScheme[(ssCookieValue-1)].checked = true;
- } else {
- colorSelect.colorScheme[(ssCookieValue-1)].checked = true;
- }
- }
-
-
- setInitialStyles();
-
-//=================================================================================
-
- function displayThemesMenu() {
-
- if (retroBrowser()) {
- return;
- }
-
- var htmstr = '<div class="themesMenu">';
- htmstr += '\n<div class="divHeader">CSS Switch Themes</div>';
-
- htmstr += '\n<div><table width="177" border="0" cellpadding="0" cellspacing="1">';
- htmstr += '\n<div><form id="colorSelect" action="#" onSubmit="return false">';
-
- htmstr += '\n<tr class="bg1">';
- htmstr += '\n<td>';
- htmstr += '\n<div><label for="www1">-1-</label></div>';
- htmstr += '\n<div><input id="www1" name="colorScheme" type="radio" onClick="changeScheme(1)"></div>';
- htmstr += '\n</td>';
-
- htmstr += '\n<td>';
- htmstr += '\n<div><label for="www2">-2-</label></div>';
- htmstr += '\n<div><input id="www2" name="colorScheme" type="radio" onClick="changeScheme(2)"></div>';
- htmstr += '\n</td>';
-
- htmstr += '\n<td>';
- htmstr += '\n<div><label for="www3">-3-</label></div>';
- htmstr += '\n<div><input id="www3" name="colorScheme" type="radio" onClick="changeScheme(3)"></div>';
- htmstr += '\n</td>';
-
- htmstr += '\n<td>';
- htmstr += '\n<div><label for="www4">-4-</label></div>';
- htmstr += '\n<div><input id="www4" name="colorScheme" type="radio" onClick="changeScheme(4)"></div>';
- htmstr += '\n</td>';
-
- htmstr += '\n<td>';
- htmstr += '\n<div><label for="www5">-5-</label></div>';
- htmstr += '\n<div><input id="www5" name="colorScheme" type="radio" onClick="changeScheme(5)"></div>';
- htmstr += '\n</td>';
-
- htmstr += '\n<td>';
- htmstr += '\n<div><label for="www6">-6-</label></div>';
- htmstr += '\n<div><input id="www6" name="colorScheme" type="radio" onClick="changeScheme(6)"></div>';
- htmstr += '\n</td>';
-
- htmstr += '\n</tr>';
-
- htmstr += '\n</form></div>';
- htmstr += '\n</table></div>';
-
- htmstr += '\n<div class="divData">';
- htmstr += '\n<div><a href="../site-goodies/site-development-bible.html#Theme_Switching">About Theme Switching</a></div>';
- htmstr += '\n<div><a href="../css-style-sheets/switch-style-sheets-dynamically.html">CSS Switch Styles Tutorial</a></div>';
- htmstr += '\n</div>';
-
- htmstr += '\n</div>';
-
- document.write(htmstr);
-
- if(typeof(checkRadioButton)=="function") {
- checkRadioButton();
- }
- }
-
-//=================================================================================
-
- function createCookie(name,value,days) {
-
- var expires = "";
-
- if (days) {
- var date = new Date();
- date.setTime(date.getTime()+(days*24*60*60*1000));
- expires = "; expires=" + date.toGMTString();
- }
-
- document.cookie = name + "=" + value + expires + "; path=/";
- }
-
-
- function readCookie(name) {
-
- var nameEQ = name + "=";
- var ca = document.cookie.split(';');
-
- for(var i=0;i < ca.length;i++) {
-
- var c = ca[i];
- while (c.charAt(0)==' ') {
- c = c.substring(1,c.length);
- }
-
- if (c.indexOf(nameEQ) === 0) {
- return (c.substring(nameEQ.length,c.length));
- }
- }
-
- return (null);
- }
-
-
- function eraseCookie(name) {
-
- createCookie(name,"",-1);
- }
-
-//================================================================================
-
- var namePath = location.pathname.replace(/\\/g,"/");
- var indexFile = false;
- if (namePath == "/" || namePath.match(/\/www\/index.html$/i)) {
- indexFile = true;
- } else if (namePath == "/~webwisew/") {
- indexFile = true;
- }
-
- var preFix = (indexFile) ? "" : "../";
-
- var ExchangeLinks = new Image(392,72);
- ExchangeLinks.src = preFix + "images/exchange-links-now.gif";
- var SwapLinks = new Image(392,72);
- SwapLinks.src = preFix + "images/swap-links-with-us.gif";
-
-
- function swapLinksBanner() {
-
- var htmstr = '<p>';
- htmstr += '<a href="http://webmaster.web-wise-wizard.com/" onClick="return(checkLocal(this))" onMouseOver="linksMouseover()" onMouseOut="linksMouseout()">';
- htmstr += '<img id="exchangeBanner" name="exchangeBanner" src="' + preFix + 'images/exchange-links-now.gif" width="392" height="72" class="alignCenter">';
- htmstr += '</a>';
- htmstr += '</p>';
-
- document.write(htmstr);
- }
-
-
- function linksMouseover() {
-
- if (document.getElementById) {
- document.getElementById("exchangeBanner").src = SwapLinks.src;
- } else if (document.all || document.layers) {
- document.exchangeBanner.src = SwapLinks.src;
- }
- }
-
- function linksMouseout() {
-
- if (document.getElementById) {
- document.getElementById("exchangeBanner").src = ExchangeLinks.src;
- } else if (document.all || document.layers) {
- document.exchangeBanner.src = ExchangeLinks.src;
- }
- }
-
-//=================================================================================
-
- function footerLinks(doctype,css,jsTested,icra) {
-
- var pathName = location.pathname.replace(/\\/g,"/");
- var siteIndex = false;
- if (pathName == "/" || pathName.match(/\/www\/index.html$/i)) {
- siteIndex = true;
- } else if (pathName == "/~webwisew/") {
- siteIndex = true;
- }
-
- var preFix = (siteIndex) ? "" : "../";
-
- var htmstr = '<div class="footerText">';
- htmstr += '<a href="' + preFix + 'site-goodies/online-privacy-policy.html" onClick="this.blur()">Online Privacy Policy</a>';
- htmstr += '</div>';
-
- htmstr += '<div class="footerText">';
- htmstr += '<a href="' + preFix + 'site-goodies/contact-us.html" onClick="this.blur()">Contact Us</a>';
- htmstr += '</div>';
-
- htmstr += '<div class="alignCenter">';
- htmstr += '<img src="' + preFix + 'images/pixClear.gif" alt="" width="1" height="22" class="displayBlock">';
- htmstr += '</div>';
-
- htmstr += '<div class="footerText"> ';
-
- if (doctype == "xhtml10") {
- htmstr += '<a href="http://validator.w3.org/check?uri=referer">';
- htmstr += '<img src="' + preFix + 'images/w3c-xhtml-1.0.gif"';
- htmstr += ' alt="Valid XHTML 1.0" width="88" height="31"></a>';
- } else if (doctype == "xhtml11") {
- htmstr += '<a href="http://validator.w3.org/check?uri=referer">';
- htmstr += '<img src="' + preFix + 'images/w3c-xhtml-1.1.gif"';
- htmstr += ' alt="Valid XHTML 1.1" width="88" height="31"></a>';
- } else {
- htmstr += '<a href="http://validator.w3.org/check/referer">';
- htmstr += '<img src="' + preFix + 'images/valid-html401.gif"';
- htmstr += ' alt="Valid HTML 4.01!" width="88" height="31"></a>';
- }
-
- htmstr += '<a href="http://jigsaw.w3.org/css-validator/check/referer">';
- htmstr += '<img src="' + preFix + 'images/valid-css.gif" alt="Valid CSS!" width="88" height="31"></a>';
-
- if (jsTested =="js") {
- htmstr += '<a href="http://www.web-wise-wizard.com/">';
- htmstr += '<img src="' + preFix + 'images/javascript-tested.gif" alt="JavaScript Tested" width="88" height="31"></a>';
- }
-
- htmstr += '<a href="http://www.icra.org/sitelabel/">';
- htmstr += '<img src="' + preFix + 'images/icra_sw.gif" alt="Internet Content Rating Association';
- htmstr += ' - This site is ICRA labelled" width="88" height="31"></a>';
- htmstr += pageCheckerLogo(preFix);
- htmstr += '</div>';
-
- document.write(htmstr);
- }
-
-//=================================================================================
-
- function pageCheckerLogo (preFix) {
-
- var htmstr, docDomain = (typeof(document.domain)=="unknown") ? "" : document.domain;
-
- if (docDomain.match(/web-wise-wizard.com$/i)) {
- htmstr = ' <a href="http://www.prchecker.info/" onClick="return(fullWindow(this))">';
- htmstr += '<img src="http://www.prchecker.info/PR2_img.gif" alt="Check Page Rank" border="0" width="88" height="31">';
- htmstr += '</a>';
- } else {
- htmstr = ' <img src="' + preFix + 'images/page-rank-hash.gif" alt="Page Checker Hash" border="0" width="88" height="31">';
- }
-
- return("");
- }
-
-//=================================================================================
-
+ // fullwin1.js + + // CONSTRUCTOR FUNCTION TO CREATE FULLWIN OBJECT + function _fullWin_object ( win_url, win_name, win_ref, win_features ) + { + this.win_url = win_url; + this.win_name = win_name; + this.win_ref = win_ref; + this.win_features = win_features; + } + + // DECLARE SCRIPTS ARRAY + var _fullWin = new Array; + + function _fullWindow(winURL) { + + var winName = replaceBadCharacters(winURL); + + var linkID = ""; + if (_fullWindow.arguments.length > 1 && _fullWindow.arguments[1].length > 0) { + linkID = _fullWindow.arguments[1]; + winName += linkID; + } + + // MAKE ROBUST FUNCTION - TEST ARGUMENTS FIRST + if (_fullWindow.arguments.length < 1) { + alert ( "\nPage Scripting Error!\nInvalid number of arguments passed to 'full_window' function.\n" ); + return(false); + } else if ( typeof ( winName ) != "string" || winName.length < 2) { + alert ( "\nPage Scripting Error!\nInvalid 'targetName' string passed to 'full_window' function.\n" ); + return (false); + } + + var win_num = _fullWin.length; + var found = false; + + for (var num=0; num<_fullWin.length; num++) { + + if ( winURL==_fullWin[num].win_url && winName==_fullWin[num].win_name) { + win_num = num; + found = true; + break; + } + } + + if (!found) { + + _fullWin[win_num] = new _fullWin_object ( + winURL, + winName, + null, + "" ); + } + + var fw = _fullWin[win_num]; + + // IF FULL WINDOW IS ALREADY OPEN + if (remoteWindowOpen(fw.win_ref)) { + + // BRING EXISTING WINDOW TO TOP + fw.win_ref.focus (); + return(remoteWindowOpen(fw.win_ref)); + } + + fw.win_features = full_window_features (); + + var win_ref = window.open(fw.win_url,fw.win_name,fw.win_features); + + fw.win_ref = win_ref; + + if (remoteWindowOpen(fw.win_ref)) { + fw.win_ref.focus (); + } + + var retCode = remoteWindowOpen(fw.win_ref); +// alert(retCode); + return(retCode); + } + + + function replaceBadCharacters(string) { + + // CONVERT STRING TO UPPER CASE + string = string.toUpperCase(); + + // REMOVE COMMON EXTENSION FROM END OF FILENAME + string = string.replace(/.htm|.html$|.shtml|.asp/i,""); + + // REMOVE PROTOCOL FROM BEGINNING OF URL +// string = string.replace(/^http:\/\/www.|http:\/\//i,""); + + // REMOVE ALL BAD CHARACTERS FROM REMAINING STRING + string = string.replace(/\/|:|\+|-|\.|_| |=|#|%|\?|\&|,/ig,""); + + // REDUCE LENGTH OF STRING TO 12 + string = string.substr(string.length-12,12); + + return(string); + } + + + function full_window_features () + { + var featuresList = "directories=yes"; + + if ( navigator.userAgent.indexOf ( "Opera" ) > -1 ) { + featuresList += ",top=0"; // doesn't WORK + featuresList += ",left=0"; // doesn't WORK + featuresList += ",height=" + screen.availHeight; + featuresList += ",width=" + screen.availWidth; + } else if ( navigator.userAgent.indexOf ( "Gecko" ) > -1 ) { + featuresList += ",top=" + screen.availTop; + featuresList += ",left=" + screen.availLeft; + featuresList += ",height=" + ( screen.availHeight - 144 ); + featuresList += ",width=" + ( screen.availWidth - 7 ); + } else if ( document.all ) { + featuresList += ",top=" + parseInt(screen.availTop,10); + featuresList += ",left=" + parseInt(screen.availLeft,10); + featuresList += ",height=" + screen.availHeight; + featuresList += ",width=" + screen.availWidth; + } else if ( document.layers ) { + featuresList += ",top=" + screen.availTop; + featuresList += ",left=" + screen.availLeft; + featuresList += ",height=" + ( screen.availHeight - 157 ); + featuresList += ",width=" + ( screen.availWidth - 11 ); + } else if ( navigator.javaEnabled () ) { + var toolkit = java.awt.Toolkit.getDefaultToolkit (); + var screen_size = toolkit.getScreenSize (); + featuresList += ",width=" + ( screen_size.width - 13 ); + featuresList += ",height=" + ( screen_size.height - 194 ); + } else if ( typeof ( screen ) == "object" ) { + featuresList += ",top=" + screen.availTop; + featuresList += ",left=" + screen.availLeft; + featuresList += ",height=" + screen.availHeight; + featuresList += ",width=" + screen.availWidth; + } + + featuresList += ",location=1"; + featuresList += ",menubar=1"; + featuresList += ",scrollbars=1"; + featuresList += ",status=1"; + featuresList += ",toolbar=1"; + featuresList += ",resizable=1"; + featuresList += ",fullscreen=0"; + + return(featuresList); + } + + + // CROSS PLATFORM, BOOLEAN, ERROR FREE TEST TO CHECK IF REMOTE WINDOW IS OPEN + function remoteWindowOpen(window_reference) { + + if (window_reference !== null && window_reference.closed === false) { + return(true); + } + + return(false); + } + +//================================================================================= + + function getMe() { + + var prot = '\x6D' + '\x61\x69\x6C' + '\x74\x6F'; + var addr = "\x48\x61d\x6Cey\x47\x40\x77eb\x2D\x77\x69se\x2D\x77\x69zard\x2E\x63\x6F\x6D"; + + var htmstr = '<div> </div><div class="mailLink">'; + htmstr += 'E\x6D\x61il: <a href="' + prot + '\x3A' + addr + '">' + addr + '</a></div>'; + + document.write(htmstr); + } + +//================================================================================= + +// themes.js + +//================================================================================= + + var pathName = location.pathname.replace(/\\/g,"/"); + + var siteIndex = false; + if (pathName == "/" || pathName.match(/\/www\/index.html$/i)) { + siteIndex = true; + } else if (pathName == "/~webwisew/") { + siteIndex = true; + } else if (pathName == "/webmaste/www/") { + siteIndex = true; + } + + var imgObj = new Array(); + var imgArr = new Array(); + var imgArray = new Array ( + "line-horz-1.gif", + "line-horz-2.gif", + "line-horz-3.gif", + "line-horz-4.gif", + "theme-back.jpg", + "deadlink-back.gif", + "hoverlink-back.gif" ); + + + function preloadThemeImages(skinNo) { + + if (skinNo < 1 || skinNo > 6) { + return; + } + + var skinStr = "0" + skinNo; + var preFix = (siteIndex) ? "" : "../"; + var imgPath = preFix + "images/skin-" + skinStr + "/"; + + for (var count=0; count<imgArray.length; count++) { + imgObj[count] = new Image(); + imgObj[count].src = imgPath + imgArray[count]; + } + } + + + var maxTheme = 6; + var _startTheme = _endTheme = 0; + + + function preloadOtherImages() { + + var skinStr, imgPath, arrayNum = -1; + + for (var skin=1; skin<7; skin++) { + + if (skin == _startTheme) { + continue; + } + + skinStr = "0" + skin; + var preFix = (siteIndex) ? "" : "../"; + imgPath = preFix + "images/skin-" + skinStr + "/"; + if (siteIndex) { + imgPath = imgPath.replace(/^..\//,""); + } + + arrayNum ++; + imgArr[arrayNum] = new Array(); + for (var count=0; count<imgArray.length; count++) { + imgArr[arrayNum][count] = new Image(); + imgArr[arrayNum][count].src = imgPath + imgArray[count]; + } + + } + } + +// window.onload=preloadOtherImages + +//================================================================================= + + var ssCookieName = "colorSelected"; + var ssCookieDays = 10; + var ssCookieValue = 1; + + function setInitialStyles() { + + if (retroBrowser()) { + return; + } + + ssCookieValue = readCookie(ssCookieName); + ssCookieValue = (ssCookieValue<1 || ssCookieValue>maxTheme) ? 1 : ssCookieValue; + _startTheme = _endTheme = ssCookieValue; + + if (navigator.appName.match(/^Microsoft/i)) { + preloadThemeImages(ssCookieValue); + switchStyleSheetMicrosoft(ssCookieValue); + } else if (navigator.appName.match(/^Netscape/i)) { + preloadThemeImages(ssCookieValue); + switchStyleSheetGecko(ssCookieValue); + } + } + + + function changeScheme(toNum) { + + if (retroBrowser()) { + return; + } + + if (navigator.appName.match(/^Microsoft/i)) { + preloadThemeImages(toNum); + switchStyleSheetMicrosoft(toNum); + } else if (navigator.appName.match(/^Netscape/i)) { + preloadThemeImages(toNum); + switchStyleSheetGecko(toNum); + } + + ssCookieValue = toNum; + createCookie(ssCookieName,ssCookieValue,ssCookieDays); + _endTheme = toNum; + } + + + function retroBrowser () { + + if (document.layers) { + return(true); + } else if (navigator.userAgent.match(/Opera/ig)) { + return(true); + } else if (navigator.userAgent.match(/Safari/ig)) { + return(true); + } + + return(false); + } + + + function switchStyleSheetMicrosoft(toNum) { + + var preFix = (siteIndex) ? "" : "../"; + + if (document.styleSheets[0].href !== null) { + document.styleSheets[0].href = preFix + "css/www-theme-" + toNum + ".css"; + } + } + + + function switchStyleSheetGecko(toNum) { + + var linkTag, linkTitle = "skin" + toNum; + var linksArray = document.getElementsByTagName("link"); + + for(var linkNum=0; linkNum<linksArray.length; linkNum++) { + linkTag = linksArray[linkNum]; + if(linkTag.getAttribute("rel").match(/^sty|^alt/i)) { + + if (linkTag.getAttribute("title") == linkTitle) { + linkTag.disabled = false; + } else if (linkTag.getAttribute("title")) { + linkTag.disabled = true; + } + } + } + } + + + function checkRadioButton() { + + var form; + + if (document.getElementById) { + form = document.getElementById('colorSelect'); + form.colorScheme[(ssCookieValue-1)].checked = true; + } else { + colorSelect.colorScheme[(ssCookieValue-1)].checked = true; + } + } + + + setInitialStyles(); + +//================================================================================= + + function displayThemesMenu() { + + if (retroBrowser()) { + return; + } + + var htmstr = '<div class="themesMenu">'; + htmstr += '\n<div class="divHeader">CSS Switch Themes</div>'; + + htmstr += '\n<div><table width="177" border="0" cellpadding="0" cellspacing="1">'; + htmstr += '\n<div><form id="colorSelect" action="#" onSubmit="return false">'; + + htmstr += '\n<tr class="bg1">'; + htmstr += '\n<td>'; + htmstr += '\n<div><label for="www1">-1-</label></div>'; + htmstr += '\n<div><input id="www1" name="colorScheme" type="radio" onClick="changeScheme(1)"></div>'; + htmstr += '\n</td>'; + + htmstr += '\n<td>'; + htmstr += '\n<div><label for="www2">-2-</label></div>'; + htmstr += '\n<div><input id="www2" name="colorScheme" type="radio" onClick="changeScheme(2)"></div>'; + htmstr += '\n</td>'; + + htmstr += '\n<td>'; + htmstr += '\n<div><label for="www3">-3-</label></div>'; + htmstr += '\n<div><input id="www3" name="colorScheme" type="radio" onClick="changeScheme(3)"></div>'; + htmstr += '\n</td>'; + + htmstr += '\n<td>'; + htmstr += '\n<div><label for="www4">-4-</label></div>'; + htmstr += '\n<div><input id="www4" name="colorScheme" type="radio" onClick="changeScheme(4)"></div>'; + htmstr += '\n</td>'; + + htmstr += '\n<td>'; + htmstr += '\n<div><label for="www5">-5-</label></div>'; + htmstr += '\n<div><input id="www5" name="colorScheme" type="radio" onClick="changeScheme(5)"></div>'; + htmstr += '\n</td>'; + + htmstr += '\n<td>'; + htmstr += '\n<div><label for="www6">-6-</label></div>'; + htmstr += '\n<div><input id="www6" name="colorScheme" type="radio" onClick="changeScheme(6)"></div>'; + htmstr += '\n</td>'; + + htmstr += '\n</tr>'; + + htmstr += '\n</form></div>'; + htmstr += '\n</table></div>'; + + htmstr += '\n<div class="divData">'; + htmstr += '\n<div><a href="../site-goodies/site-development-bible.html#Theme_Switching">About Theme Switching</a></div>'; + htmstr += '\n<div><a href="../css-style-sheets/switch-style-sheets-dynamically.html">CSS Switch Styles Tutorial</a></div>'; + htmstr += '\n</div>'; + + htmstr += '\n</div>'; + + document.write(htmstr); + + if(typeof(checkRadioButton)=="function") { + checkRadioButton(); + } + } + +//================================================================================= + + function createCookie(name,value,days) { + + var expires = ""; + + if (days) { + var date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + expires = "; expires=" + date.toGMTString(); + } + + document.cookie = name + "=" + value + expires + "; path=/"; + } + + + function readCookie(name) { + + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + + for(var i=0;i < ca.length;i++) { + + var c = ca[i]; + while (c.charAt(0)==' ') { + c = c.substring(1,c.length); + } + + if (c.indexOf(nameEQ) === 0) { + return (c.substring(nameEQ.length,c.length)); + } + } + + return (null); + } + + + function eraseCookie(name) { + + createCookie(name,"",-1); + } + +//================================================================================ + + var namePath = location.pathname.replace(/\\/g,"/"); + var indexFile = false; + if (namePath == "/" || namePath.match(/\/www\/index.html$/i)) { + indexFile = true; + } else if (namePath == "/~webwisew/") { + indexFile = true; + } + + var preFix = (indexFile) ? "" : "../"; + + var ExchangeLinks = new Image(392,72); + ExchangeLinks.src = preFix + "images/exchange-links-now.gif"; + var SwapLinks = new Image(392,72); + SwapLinks.src = preFix + "images/swap-links-with-us.gif"; + + + function swapLinksBanner() { + + var htmstr = '<p>'; + htmstr += '<a href="http://webmaster.web-wise-wizard.com/" onClick="return(checkLocal(this))" onMouseOver="linksMouseover()" onMouseOut="linksMouseout()">'; + htmstr += '<img id="exchangeBanner" name="exchangeBanner" src="' + preFix + 'images/exchange-links-now.gif" width="392" height="72" class="alignCenter">'; + htmstr += '</a>'; + htmstr += '</p>'; + + document.write(htmstr); + } + + + function linksMouseover() { + + if (document.getElementById) { + document.getElementById("exchangeBanner").src = SwapLinks.src; + } else if (document.all || document.layers) { + document.exchangeBanner.src = SwapLinks.src; + } + } + + function linksMouseout() { + + if (document.getElementById) { + document.getElementById("exchangeBanner").src = ExchangeLinks.src; + } else if (document.all || document.layers) { + document.exchangeBanner.src = ExchangeLinks.src; + } + } + +//================================================================================= + + function footerLinks(doctype,css,jsTested,icra) { + + var pathName = location.pathname.replace(/\\/g,"/"); + var siteIndex = false; + if (pathName == "/" || pathName.match(/\/www\/index.html$/i)) { + siteIndex = true; + } else if (pathName == "/~webwisew/") { + siteIndex = true; + } + + var preFix = (siteIndex) ? "" : "../"; + + var htmstr = '<div class="footerText">'; + htmstr += '<a href="' + preFix + 'site-goodies/online-privacy-policy.html" onClick="this.blur()">Online Privacy Policy</a>'; + htmstr += '</div>'; + + htmstr += '<div class="footerText">'; + htmstr += '<a href="' + preFix + 'site-goodies/contact-us.html" onClick="this.blur()">Contact Us</a>'; + htmstr += '</div>'; + + htmstr += '<div class="alignCenter">'; + htmstr += '<img src="' + preFix + 'images/pixClear.gif" alt="" width="1" height="22" class="displayBlock">'; + htmstr += '</div>'; + + htmstr += '<div class="footerText"> '; + + if (doctype == "xhtml10") { + htmstr += '<a href="http://validator.w3.org/check?uri=referer">'; + htmstr += '<img src="' + preFix + 'images/w3c-xhtml-1.0.gif"'; + htmstr += ' alt="Valid XHTML 1.0" width="88" height="31"></a>'; + } else if (doctype == "xhtml11") { + htmstr += '<a href="http://validator.w3.org/check?uri=referer">'; + htmstr += '<img src="' + preFix + 'images/w3c-xhtml-1.1.gif"'; + htmstr += ' alt="Valid XHTML 1.1" width="88" height="31"></a>'; + } else { + htmstr += '<a href="http://validator.w3.org/check/referer">'; + htmstr += '<img src="' + preFix + 'images/valid-html401.gif"'; + htmstr += ' alt="Valid HTML 4.01!" width="88" height="31"></a>'; + } + + htmstr += '<a href="http://jigsaw.w3.org/css-validator/check/referer">'; + htmstr += '<img src="' + preFix + 'images/valid-css.gif" alt="Valid CSS!" width="88" height="31"></a>'; + + if (jsTested =="js") { + htmstr += '<a href="http://www.web-wise-wizard.com/">'; + htmstr += '<img src="' + preFix + 'images/javascript-tested.gif" alt="JavaScript Tested" width="88" height="31"></a>'; + } + + htmstr += '<a href="http://www.icra.org/sitelabel/">'; + htmstr += '<img src="' + preFix + 'images/icra_sw.gif" alt="Internet Content Rating Association'; + htmstr += ' - This site is ICRA labelled" width="88" height="31"></a>'; + htmstr += pageCheckerLogo(preFix); + htmstr += '</div>'; + + document.write(htmstr); + } + +//================================================================================= + + function pageCheckerLogo (preFix) { + + var htmstr, docDomain = (typeof(document.domain)=="unknown") ? "" : document.domain; + + if (docDomain.match(/web-wise-wizard.com$/i)) { + htmstr = ' <a href="http://www.prchecker.info/" onClick="return(fullWindow(this))">'; + htmstr += '<img src="http://www.prchecker.info/PR2_img.gif" alt="Check Page Rank" border="0" width="88" height="31">'; + htmstr += '</a>'; + } else { + htmstr = ' <img src="' + preFix + 'images/page-rank-hash.gif" alt="Page Checker Hash" border="0" width="88" height="31">'; + } + + return(""); + } + +//================================================================================= + diff --git a/docview/docs/ascii-ibm-extended-character-set_files/www-content.css b/docview/docs/ascii-ibm-extended-character-set_files/www-content.css index 6940a88b..2a73c6d9 100644 --- a/docview/docs/ascii-ibm-extended-character-set_files/www-content.css +++ b/docview/docs/ascii-ibm-extended-character-set_files/www-content.css @@ -1,800 +1,800 @@ -/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */
-
-.dummy {
- font-family:verdana, arial, helvetica, sans-serif;
-}
-
-/* PAGE LAYOUT STYLES */
-
-#mainContainer {
-margin-left:20px;
-margin-right:200px;
-}
-
-#mainContent {
-margin-left:0;
-margin-top:0;
-margin-right:0;
-}
-
-#rightContainer1 {
-position:absolute;
-top:171px;
-right:0;
-width:180px;
-margin-right:0;
-}
-
-#rightContainer2 {
-position:absolute;
-top:194px;
-right:0;
-width:180px;
-margin-right:0;
-}
-
-#rightContent {
-margin:0;
-border-left:3px double #858654;
-border-bottom:3px double #858654;
-}
-
-/* ======= UNIVERSAL PAGE CONTENT FORMATTING STYLES ======= */
-
-.setOuterMargins {
- margin-left:30px;
- margin-right:30px;
-}
-
-hr {
- width:100%;
- height:1px;
- color:#858654;
-}
-
-/* ======= START OF TEXT AND LINK STYLES ======= */
-
-.redBox {
- border:3px double #CC3333;
- padding:7px;
- color:#000000;
- text-align:justify;
- font-family:Tahoma,serif,Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-style:normal;
- background-color:#FFFFFF;
-}
-
-/* ======= START OF TEXT AND LINK STYLES ======= */
-
-.inlineLink {
- font-family:Arial,Helvetica,sans-serif;
- font-size:11pt;
- text-decoration:underline;
-}
-
-a.inlineLink:active {color:#0000FF;}
-a.inlineLink:hover {color:#FFFFFF;}
-a.inlineLink:link {color:#000000;} /* Link colour when page is first loaded */
-a.inlineLink:visited {color:#009900;} /* Link colour if uses has previously used link */
-
-/*
-a:active .inlineLink {color:#0000FF;}
-a:hover .inlineLink {color:#FF0000;}
-a:link .inlineLink {color:#000000;}
-a:visited .inlineLink {color:#FFFF00;}
-*/
-
-
-.leftPicImg {
- clear:both;
- float:left;
- display:block;
- margin-top:19px;
- margin-right:20px;
- margin-bottom:20px;
- border: 2px outset #D8D8D8;
-}
-
-.leftPicImg2 {
- float:left;
- display:inline;
- margin-right:20px;
- margin-bottom:10px;
- border: 2px outset #D8D8D8;
-}
-
-.mailLink {
-}
-
-.mailLink a:active {color:#FFFFFF;}
-.mailLink a:hover {color:#FFFF99;}
-.mailLink a:link {color:#FFFFFF;}
-.mailLink a:visited {color:#FFFFFF;}
-
-em {
- text-transform:uppercase;
-}
-
-.centerTable {
- text-align:center;
-}
-
-.centerTable table {
- margin-left:auto;
- margin-right:auto;
- text-align:left;
-}
-
-.centerTableCa {
- text-align:center;
-}
-
-.centerTableCa table {
- margin-left:auto;
- margin-right:auto;
- text-align:center;
-}
-
-.centerTableRa {
- text-align:center;
-}
-
-.centerTableRa table {
- margin-left:auto;
- margin-right:auto;
- text-align:right;
-}
-
-.centerFieldset {
- text-align:center;
-}
-
-.centerFieldset fieldset {
- display:inline;
- margin-left:auto;
- margin-right:auto;
-}
-
-.centerFieldsetLa {
- text-align:center;
-}
-
-.centerFieldsetLa fieldset {
- display:inline;
- margin-left:auto;
- margin-right:auto;
- text-align:left;
-}
-
-.leftAlignFieldset {
- float:left;
- margin-right:20px;
- text-align:left;
-}
-
-.lAfieldset {
- display:inline;
- float:none;
- text-align:center;
- margin:0 auto;
-}
-
-.centerObject {
- text-align:center;
-}
-
-.centerObject object {
- display:inline;
- margin-left:auto;
- margin-right:auto;
-}
-
-.alignCenter {
- display:block;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-
-.fancyLink0 {
- font-family:arial,helvetica,sans-serif;
- font-weight:normal;
- font-size:9pt;
- color:#990000;
- text-align:justify;
- text-decoration:none;
-}
-
-.fancyLink0 a {
- font-family:tahoma,arial,helvetica,sans-serif;
- font-weight:bold;
- font-size:9pt;
- color:#006600;
- text-decoration:underline;
-}
-
-
-.fancyLink0 small {
- font-family:arial,helvetica,sans-serif;
- font-size:8pt;
- font-weight:normal;
- font-style:normal;
- color:#006600;
- text-decoration:underline;
-}
-
-
-.fancyLink1 {
- text-align:justify;
- line-height:0.96em;
- text-decoration:none;
-}
-
-.fancyLink1 em {
- font-size:9pt;
- font-family:tahoma,arial,helvetica,sans-serif;
- font-weight:bold;
- font-style:normal;
- text-transform:none;
- color:#006600;
- text-decoration:underline;
-}
-
-.fancyLink1 a {
- font-family:arial,helvetica,sans-serif;
- font-weight:normal;
- font-size:9pt;
- color:#990000;
- text-decoration:none;
-}
-
-.fancyLink1 small {
- font-family:arial,helvetica,sans-serif;
- font-size:8pt;
- font-weight:normal;
- font-style:normal;
- color:#006600;
- text-decoration:underline;
-}
-
-
-.generalLink {
- text-align:justify;
- font-size:9pt;
- font-family:arial,helvetica,sans-serif;
- color:#990000;
-}
-
-.generalLink a {
- font-weight:bold;
- text-decoration:underline;
-}
-
-img {
- border:0px;
-}
-
-.misPointer {
- list-style-image:url("../images/hand-red.gif");
- line-height:180%;
-}
-
-.extPointer {
- list-style-image:url("../images/hand-blue.gif");
- line-height:180%;
-}
-
-.locPointer {
- list-style-image:url("../images/hand-green.gif");
- line-height:180%;
-}
-
-/*
-ul a {
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 9pt;
- display:block;
-}
-*/
-
-.standardList {
- display:block;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 9pt;
-}
-
-.standardList li {
- line-height:120%;
-}
-
-.standardList a {
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 9pt;
- text-decoration:underline;
-}
-
-.textLink {
- display:inline;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-style:normal;
- font-size:8pt;
- cursor:pointer;
- text-decoration:underline;
-}
-
-.listStyle {
- margin-left:60px;
- margin-right:60px;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
-}
-
-.listStyle li {
- text-align:justify;
- margin-bottom:7px;
-}
-
-.noListStyle {
- list-style-type:none;
- margin-left:37px;
- margin-right:60px;
-}
-
-.listStyleNone {
- list-style-type:none;
- margin-left:37px;
- margin-right:60px;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
-}
-
-.listStyleNone li {
- text-align:justify;
- margin-bottom:7px;
-}
-
-.listStyleCircle {
- list-style-type:circle;
- margin-left:30px;
- margin-right:30px;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
-}
-
-.listStyleCircle li {
- text-align:left;
- margin-bottom:7px;
-}
-
-.listStyleCircle li a {
- font-weight:bold;
-}
-
-.listStyleSquare {
- list-style-type:square;
- margin-left:60px;
- margin-right:60px;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
-}
-
-.listStyleSquare li {
- text-align:justify;
- margin-bottom:7px;
-}
-
-.fontBold {
- font-weight:bolder;
-}
-
-.markupButtonHi {
- margin-top:5px;
- width:120px;
- background-color:#858654;
- color:#FFFFFF;
- font-family:Arial,Helvetiva,sans-serif;
- font-size:9.5pt;
- font-weight:bolder;
- border: none;
- border-right: 2px #787878 solid;
- border-bottom: 2px #787878 solid;
- border-top: 2px #DDDDDD solid;
- border-left: 2px #DDDDDD solid;
-}
-
-.markupButtonLo {
- margin-top:5px;
- width:120px;
- background-color:#BBBA93;
- color:#006600;
- font-family:Arial,Helvetiva,sans-serif;
- font-size:9.5pt;
- font-weight:bolder;
- border: none;
- border-right: 2px #787878 solid;
- border-bottom: 2px #787878 solid;
- border-top: 2px #DDDDDD solid;
- border-left: 2px #DDDDDD solid;
-}
-
-.markupTextarea {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:9.5pt;
- color:#006600;
-}
-
-.pseudoLink {
- display:inline;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10.5pt;
- font-weight:normal;
- color:#006600;
- text-decoration:underline;
- cursor:pointer;
-}
-
-
-/* START OF STYLES USED BY THE MULTI-SEARCH PAGE */
-
-.loadTitle {
- font-family:Arial,Helvetica,sans-serif;
- font-size:11pt;
- font-weight:bold;
-}
-
-/* END OF STYLES USED BY THE MULTI-SEARCH PAGE */
-
-
-.siteMap {
- display:block;
- font-family:Arial,Helvetica,sans-serif;
- margin-bottom:0;
-}
-
-.siteMap a {
- display:block;
- text-decoration:none;
-/* border: 2px solid #D2D2A5;*/
- padding:5px;
- font-size:11pt;
-}
-
-.siteMap a:hover {
- border: 2px dotted #858654;
-}
-
-.siteMap .pagePath {
- display:block;
- margin-top:0px;
-}
-
-.siteMap .pageHeading {
- display:block;
- padding-top:2px;
- font-weight:bolder;
- font-size:10pt;
- text-decoration:underline;
-}
-
-.siteMap .metaDescription {
- display:block;
- font-size:10pt;
- padding-top:2px;
- color:#990000;
- text-align:justify;
-}
-
-.siteMap .titleTag {
- display:block;
- padding-top:2px;
- font-size:10pt;
- color:#003300;
-}
-
-.sitemapLeft {
- margin-left:0%;
- width:94%;
-}
-
-.sitemapIndent {
- margin-left:6%;
- width:94%;
-}
-
-
-.quikPick {
- width:60%;
- margin:auto;
- font-family:verdana,Arial,Helvetica,sans-serif;
- font-size:0.77em;
- font-weight:bolder;
- font-style:oblique;
- background-color:#F0F0F0;
- color:#000000;
- padding:8px;
- border:2px solid #777777;
-}
-
-.quikPick div {
- margin-top:5px;
- padding-top:5px;
- padding-bottom:5px;
- text-align:justify;
- font-weight:normal;
- font-style:normal;
-}
-
-.alignLeft {
- text-align:left;
-}
-
-.alignCenter {
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-.alignCenterInline {
- display:inline;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-.alignRight {
- text-align:right;
-}
-
-#tabSelect {
- cursor:pointer;
-}
-
-.paddingTop10 {
- padding-top:10px;
-}
-
-.width20 {
- width:20px;
-}
-
-.width75p {
- width:75%;
-}
-
-.width33p {
- width:33%;
-}
-
-.width40 {
- width:40px;
-}
-
-.width50p {
- width:50%;
-}
-
-.width60 {
- width:60px;
-}
-
-.width98 {
- width:98px;
-}
-
-.width300 {
- width:300px;
-}
-
-.width340 {
- width:340px;
-}
-
-.width100p {
- width:100%;
-}
-
-.width742 {
- width:742px;
-}
-
-.height20 {
- height:20px;
-}
-
-.height30 {
- height:30px;
-}
-
-.height51 {
- height:51px;
-}
-
-.height144 {
- height:144px;
-}
-
-.padding6 {
- padding-top:6px;
- padding-bottom:6px;
-}
-
-.hspace5 {
- padding-left:5px;
- padding-right:5px;
-}
-
-.hspace16 {
- padding-left:16px;
- padding-right:16px;
-}
-
-.hmargins30 {
- margin-left:30px;
- margin-right:30px
-}
-
-.marginTop0 {
- margin-top:0px;
-}
-
-.marginTop8 {
- margin-top:8px;
-}
-
-.marginTop11 {
- margin-top:11px;
-}
-
-.marginLeft45 {
- margin-left:45px;
-}
-
-.vspace5 {
- margin-top:5px;
- margin-bottom:5px;
-}
-
-.leftObj {
- display:block;
- float:left;
- margin-top:5px;
- margin-right:16px;
- margin-bottom:10px;
- border:none;
-}
-
-.limeHeightZero {
- line-height:0px;
-}
-
-.topLeftAlignPik {
- text-align:left;
- float:left;
-}
-
-.topLeftAlignPik div {
- margin-top:21px;
-}
-
-.topLeftAlignPik img {
- display:inline;
- margin-top:4px;
- margin-right:20px;
- margin-bottom:6px;
-}
-
-.leftAlignPik {
- text-align:left;
- float:left;
-}
-
-.leftAlignPik img {
- display:inline;
- margin-top:4px;
- margin-right:20px;
- margin-bottom:6px;
-}
-
-.leftAlignPik iframe {
- display:inline;
- margin-top:4px;
- margin-right:20px;
- margin-bottom:6px;
-}
-
-.borderInset {
- border: 2px inset #D8D8D8;
-}
-
-.borderOutset {
- border: 2px outset #D8D8D8;
-}
-
-.picTable {
- display:inline;
- margin-left:0px;
- margin-right:30px;
- margin-bottom:10px;
- float:left;
-}
-
-.clearLeft {
- clear:left;
-}
-
-.leftAlign {
- text-align:left;
-}
-
-.displayBlock {
- clear:both;
- display:block;
-}
-
-.displayInline {
- display:inline;
-}
-
-.inlineLeft {
- display:inline;
- text-align:left;
-}
-
-.displayLinkRank {
- clear:both;
- text-align:left;
- display:block;
- margin-top:3px;
- margin-bottom:3px;
-}
-
-.whoisLookup {
- text-align:center;
- border:1px solid #000000;
-}
-
-.whoisLookup .big {
- margin:9px;
- font-size:13pt;
- font-weight:bold;
-}
-
-.linkToPage {
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
- color:#000000;
-}
-
-.linkToPage span {
- display:block;
- text-decoration:underline;
- font-weight:bold;
- color:#0000CC;
-}
-
-.radioCursor {cursor:pointer;}
-.radioCursor label {cursor:pointer;}
-.radioCursor input {cursor:pointer;}
-
-.tt {
- font-family:monospace;
- font-size:smaller;
-}
+/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */ + +.dummy { + font-family:verdana, arial, helvetica, sans-serif; +} + +/* PAGE LAYOUT STYLES */ + +#mainContainer { +margin-left:20px; +margin-right:200px; +} + +#mainContent { +margin-left:0; +margin-top:0; +margin-right:0; +} + +#rightContainer1 { +position:absolute; +top:171px; +right:0; +width:180px; +margin-right:0; +} + +#rightContainer2 { +position:absolute; +top:194px; +right:0; +width:180px; +margin-right:0; +} + +#rightContent { +margin:0; +border-left:3px double #858654; +border-bottom:3px double #858654; +} + +/* ======= UNIVERSAL PAGE CONTENT FORMATTING STYLES ======= */ + +.setOuterMargins { + margin-left:30px; + margin-right:30px; +} + +hr { + width:100%; + height:1px; + color:#858654; +} + +/* ======= START OF TEXT AND LINK STYLES ======= */ + +.redBox { + border:3px double #CC3333; + padding:7px; + color:#000000; + text-align:justify; + font-family:Tahoma,serif,Geneva,Verdana,Arial,Helvetica,sans-serif; + font-size:9pt; + font-style:normal; + background-color:#FFFFFF; +} + +/* ======= START OF TEXT AND LINK STYLES ======= */ + +.inlineLink { + font-family:Arial,Helvetica,sans-serif; + font-size:11pt; + text-decoration:underline; +} + +a.inlineLink:active {color:#0000FF;} +a.inlineLink:hover {color:#FFFFFF;} +a.inlineLink:link {color:#000000;} /* Link colour when page is first loaded */ +a.inlineLink:visited {color:#009900;} /* Link colour if uses has previously used link */ + +/* +a:active .inlineLink {color:#0000FF;} +a:hover .inlineLink {color:#FF0000;} +a:link .inlineLink {color:#000000;} +a:visited .inlineLink {color:#FFFF00;} +*/ + + +.leftPicImg { + clear:both; + float:left; + display:block; + margin-top:19px; + margin-right:20px; + margin-bottom:20px; + border: 2px outset #D8D8D8; +} + +.leftPicImg2 { + float:left; + display:inline; + margin-right:20px; + margin-bottom:10px; + border: 2px outset #D8D8D8; +} + +.mailLink { +} + +.mailLink a:active {color:#FFFFFF;} +.mailLink a:hover {color:#FFFF99;} +.mailLink a:link {color:#FFFFFF;} +.mailLink a:visited {color:#FFFFFF;} + +em { + text-transform:uppercase; +} + +.centerTable { + text-align:center; +} + +.centerTable table { + margin-left:auto; + margin-right:auto; + text-align:left; +} + +.centerTableCa { + text-align:center; +} + +.centerTableCa table { + margin-left:auto; + margin-right:auto; + text-align:center; +} + +.centerTableRa { + text-align:center; +} + +.centerTableRa table { + margin-left:auto; + margin-right:auto; + text-align:right; +} + +.centerFieldset { + text-align:center; +} + +.centerFieldset fieldset { + display:inline; + margin-left:auto; + margin-right:auto; +} + +.centerFieldsetLa { + text-align:center; +} + +.centerFieldsetLa fieldset { + display:inline; + margin-left:auto; + margin-right:auto; + text-align:left; +} + +.leftAlignFieldset { + float:left; + margin-right:20px; + text-align:left; +} + +.lAfieldset { + display:inline; + float:none; + text-align:center; + margin:0 auto; +} + +.centerObject { + text-align:center; +} + +.centerObject object { + display:inline; + margin-left:auto; + margin-right:auto; +} + +.alignCenter { + display:block; + text-align:center; + margin-left:auto; + margin-right:auto; +} + + +.fancyLink0 { + font-family:arial,helvetica,sans-serif; + font-weight:normal; + font-size:9pt; + color:#990000; + text-align:justify; + text-decoration:none; +} + +.fancyLink0 a { + font-family:tahoma,arial,helvetica,sans-serif; + font-weight:bold; + font-size:9pt; + color:#006600; + text-decoration:underline; +} + + +.fancyLink0 small { + font-family:arial,helvetica,sans-serif; + font-size:8pt; + font-weight:normal; + font-style:normal; + color:#006600; + text-decoration:underline; +} + + +.fancyLink1 { + text-align:justify; + line-height:0.96em; + text-decoration:none; +} + +.fancyLink1 em { + font-size:9pt; + font-family:tahoma,arial,helvetica,sans-serif; + font-weight:bold; + font-style:normal; + text-transform:none; + color:#006600; + text-decoration:underline; +} + +.fancyLink1 a { + font-family:arial,helvetica,sans-serif; + font-weight:normal; + font-size:9pt; + color:#990000; + text-decoration:none; +} + +.fancyLink1 small { + font-family:arial,helvetica,sans-serif; + font-size:8pt; + font-weight:normal; + font-style:normal; + color:#006600; + text-decoration:underline; +} + + +.generalLink { + text-align:justify; + font-size:9pt; + font-family:arial,helvetica,sans-serif; + color:#990000; +} + +.generalLink a { + font-weight:bold; + text-decoration:underline; +} + +img { + border:0px; +} + +.misPointer { + list-style-image:url("../images/hand-red.gif"); + line-height:180%; +} + +.extPointer { + list-style-image:url("../images/hand-blue.gif"); + line-height:180%; +} + +.locPointer { + list-style-image:url("../images/hand-green.gif"); + line-height:180%; +} + +/* +ul a { + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 9pt; + display:block; +} +*/ + +.standardList { + display:block; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 9pt; +} + +.standardList li { + line-height:120%; +} + +.standardList a { + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 9pt; + text-decoration:underline; +} + +.textLink { + display:inline; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-style:normal; + font-size:8pt; + cursor:pointer; + text-decoration:underline; +} + +.listStyle { + margin-left:60px; + margin-right:60px; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; +} + +.listStyle li { + text-align:justify; + margin-bottom:7px; +} + +.noListStyle { + list-style-type:none; + margin-left:37px; + margin-right:60px; +} + +.listStyleNone { + list-style-type:none; + margin-left:37px; + margin-right:60px; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; +} + +.listStyleNone li { + text-align:justify; + margin-bottom:7px; +} + +.listStyleCircle { + list-style-type:circle; + margin-left:30px; + margin-right:30px; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; +} + +.listStyleCircle li { + text-align:left; + margin-bottom:7px; +} + +.listStyleCircle li a { + font-weight:bold; +} + +.listStyleSquare { + list-style-type:square; + margin-left:60px; + margin-right:60px; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; +} + +.listStyleSquare li { + text-align:justify; + margin-bottom:7px; +} + +.fontBold { + font-weight:bolder; +} + +.markupButtonHi { + margin-top:5px; + width:120px; + background-color:#858654; + color:#FFFFFF; + font-family:Arial,Helvetiva,sans-serif; + font-size:9.5pt; + font-weight:bolder; + border: none; + border-right: 2px #787878 solid; + border-bottom: 2px #787878 solid; + border-top: 2px #DDDDDD solid; + border-left: 2px #DDDDDD solid; +} + +.markupButtonLo { + margin-top:5px; + width:120px; + background-color:#BBBA93; + color:#006600; + font-family:Arial,Helvetiva,sans-serif; + font-size:9.5pt; + font-weight:bolder; + border: none; + border-right: 2px #787878 solid; + border-bottom: 2px #787878 solid; + border-top: 2px #DDDDDD solid; + border-left: 2px #DDDDDD solid; +} + +.markupTextarea { + font-family:Arial,Helvetiva,sans-serif; + font-size:9.5pt; + color:#006600; +} + +.pseudoLink { + display:inline; + font-family:Arial,Helvetica,sans-serif; + font-size:10.5pt; + font-weight:normal; + color:#006600; + text-decoration:underline; + cursor:pointer; +} + + +/* START OF STYLES USED BY THE MULTI-SEARCH PAGE */ + +.loadTitle { + font-family:Arial,Helvetica,sans-serif; + font-size:11pt; + font-weight:bold; +} + +/* END OF STYLES USED BY THE MULTI-SEARCH PAGE */ + + +.siteMap { + display:block; + font-family:Arial,Helvetica,sans-serif; + margin-bottom:0; +} + +.siteMap a { + display:block; + text-decoration:none; +/* border: 2px solid #D2D2A5;*/ + padding:5px; + font-size:11pt; +} + +.siteMap a:hover { + border: 2px dotted #858654; +} + +.siteMap .pagePath { + display:block; + margin-top:0px; +} + +.siteMap .pageHeading { + display:block; + padding-top:2px; + font-weight:bolder; + font-size:10pt; + text-decoration:underline; +} + +.siteMap .metaDescription { + display:block; + font-size:10pt; + padding-top:2px; + color:#990000; + text-align:justify; +} + +.siteMap .titleTag { + display:block; + padding-top:2px; + font-size:10pt; + color:#003300; +} + +.sitemapLeft { + margin-left:0%; + width:94%; +} + +.sitemapIndent { + margin-left:6%; + width:94%; +} + + +.quikPick { + width:60%; + margin:auto; + font-family:verdana,Arial,Helvetica,sans-serif; + font-size:0.77em; + font-weight:bolder; + font-style:oblique; + background-color:#F0F0F0; + color:#000000; + padding:8px; + border:2px solid #777777; +} + +.quikPick div { + margin-top:5px; + padding-top:5px; + padding-bottom:5px; + text-align:justify; + font-weight:normal; + font-style:normal; +} + +.alignLeft { + text-align:left; +} + +.alignCenter { + text-align:center; + margin-left:auto; + margin-right:auto; +} + +.alignCenterInline { + display:inline; + text-align:center; + margin-left:auto; + margin-right:auto; +} + +.alignRight { + text-align:right; +} + +#tabSelect { + cursor:pointer; +} + +.paddingTop10 { + padding-top:10px; +} + +.width20 { + width:20px; +} + +.width75p { + width:75%; +} + +.width33p { + width:33%; +} + +.width40 { + width:40px; +} + +.width50p { + width:50%; +} + +.width60 { + width:60px; +} + +.width98 { + width:98px; +} + +.width300 { + width:300px; +} + +.width340 { + width:340px; +} + +.width100p { + width:100%; +} + +.width742 { + width:742px; +} + +.height20 { + height:20px; +} + +.height30 { + height:30px; +} + +.height51 { + height:51px; +} + +.height144 { + height:144px; +} + +.padding6 { + padding-top:6px; + padding-bottom:6px; +} + +.hspace5 { + padding-left:5px; + padding-right:5px; +} + +.hspace16 { + padding-left:16px; + padding-right:16px; +} + +.hmargins30 { + margin-left:30px; + margin-right:30px +} + +.marginTop0 { + margin-top:0px; +} + +.marginTop8 { + margin-top:8px; +} + +.marginTop11 { + margin-top:11px; +} + +.marginLeft45 { + margin-left:45px; +} + +.vspace5 { + margin-top:5px; + margin-bottom:5px; +} + +.leftObj { + display:block; + float:left; + margin-top:5px; + margin-right:16px; + margin-bottom:10px; + border:none; +} + +.limeHeightZero { + line-height:0px; +} + +.topLeftAlignPik { + text-align:left; + float:left; +} + +.topLeftAlignPik div { + margin-top:21px; +} + +.topLeftAlignPik img { + display:inline; + margin-top:4px; + margin-right:20px; + margin-bottom:6px; +} + +.leftAlignPik { + text-align:left; + float:left; +} + +.leftAlignPik img { + display:inline; + margin-top:4px; + margin-right:20px; + margin-bottom:6px; +} + +.leftAlignPik iframe { + display:inline; + margin-top:4px; + margin-right:20px; + margin-bottom:6px; +} + +.borderInset { + border: 2px inset #D8D8D8; +} + +.borderOutset { + border: 2px outset #D8D8D8; +} + +.picTable { + display:inline; + margin-left:0px; + margin-right:30px; + margin-bottom:10px; + float:left; +} + +.clearLeft { + clear:left; +} + +.leftAlign { + text-align:left; +} + +.displayBlock { + clear:both; + display:block; +} + +.displayInline { + display:inline; +} + +.inlineLeft { + display:inline; + text-align:left; +} + +.displayLinkRank { + clear:both; + text-align:left; + display:block; + margin-top:3px; + margin-bottom:3px; +} + +.whoisLookup { + text-align:center; + border:1px solid #000000; +} + +.whoisLookup .big { + margin:9px; + font-size:13pt; + font-weight:bold; +} + +.linkToPage { + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; + color:#000000; +} + +.linkToPage span { + display:block; + text-decoration:underline; + font-weight:bold; + color:#0000CC; +} + +.radioCursor {cursor:pointer;} +.radioCursor label {cursor:pointer;} +.radioCursor input {cursor:pointer;} + +.tt { + font-family:monospace; + font-size:smaller; +} diff --git a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-1.css b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-1.css index b446cfb7..cdacf632 100644 --- a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-1.css +++ b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-1.css @@ -1,786 +1,786 @@ -/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */
-
-.dummy {
- font-family:verdana, arial, helvetica, sans-serif;
-}
-
-
-/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */
-
-body {
- margin:0px;
- padding:0px;
- background-color:#F1F4FE;
- font-size: 100% !important;
- line-height: normal !important;
-}
-
-.headerArea {
- height:120px;
- margin:0px;
- padding:0px;
- line-height:60%;
- text-align:center;
- color:#FFFFFF;
- background-color:#565D82;
- background-image:url('../images/skin-01/theme-back.jpg');
-}
-
-.headerArea a {
- color:#FFFFFF;
-}
-
-.headerArea img {
- margin-left:auto;
- margin-right:auto;
-}
-
-.h1 {
- font-family: verdana,arial,helvetiva,sans-serif;
- font-size:15pt;
- font-weight:normal;
- color:#003300;
- border:3px #565D82 double;
- padding-top:4px;
- padding-bottom:6px;
- width:60%;
- margin:0 auto;
- background-color:#CDD8FF;
- text-align:center;
-}
-
-.h2 {
- margin-top:20px;
- padding:0px;
- font-family:"Comic Sans MS","VagRounded BT","Impress BT",cursive;
- font-size:1.17em;
- font-weight:normal;
- color:#006600;
-}
-
-
-.h3 {
- clear:both;
- padding-top:16px;
- padding-bottom:8px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 10pt;
- color: #006600;
-}
-
-.h3 span {
- display:inline;
- border-top: 1px #666666 solid;
- border-bottom: 1px #666666 solid;
- padding:0;
- padding-top: 5px;
- padding-bottom: 5px;
- margin:0;
-}
-
-.bestViewed {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:26px;
- margin:0 auto;
-}
-
-.pageMessage {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:16px;
- margin:0 auto;
- margin-bottom:30px;
-}
-
-.footerArea {
- clear:both;
- width:100%;
- text-align:center;
- color:#FFFFFF;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.71em;
- padding-top:0px;
- background-color:#565D82;
- background-image:url('../images/skin-01/theme-back.jpg');
-}
-
-.footerText {
- padding-top:4px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
-}
-
-.footerText a {
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
- text-decoration:underline;
-}
-
-.footerText a:link {color: #FFFFFF; text-decoration: underline;}
-.footerText a:visited {color: #FFFFFF; text-decoration: underline;}
-.footerText a:hover {color: #FFFF00; text-decoration: underline;}
-.footerText a:focus {color: #FF0000; text-decoration: underline;}
-.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;}
-
-
-/* ======= UNIVERSAL MAIN-MENU STYLES ======= */
-
-
-.mainMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#565D82;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu li {
- display:inline;
-}
-
-.mainMenu a {
- float:left;
- width:90px;
- color:#FFFFFF;
- background-color:#565D82;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #FFFFFF;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #FFFFFF;
- text-align:center;
- font-size:9pt;
- font-weight:bold;
- color:#6A5A00;
- background-color:#FFFFFF;
- background-image:url('../images/skin-01/deadlink-back.gif');
-}
-
-.mainMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-01/hoverlink-back.gif');
-}
-
-
-/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */
-
-
-.subMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#CDD8FF;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu li {
- display:inline;
-}
-
-.subMenu a {
- float:left;
- width:90px;
- color:#6A5A00;
- background-color:#CDD8FF;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #565D82;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #858654;
- text-align:center;
- color:#6A5A00;
- background-color:#FFFFFF;
- background-image:url('../images/skin-01/deadlink-back.gif');
- background-position: 0px -1px;
-}
-
-.subMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-01/hoverlink-back.gif');
- background-position: 0px -1px;
-}
-
-
-/* ======= SITE TABLES/BOXES STYLES ======= */
-
-.siteTable {
- background-color:#565D82;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
-}
-
-.siteTable .bg0 {
- background-color:#565D82;
- color:#FFFFFF;
-}
-
-.siteTable .bg1 {
- background-color:#F1F4FE;
- color:#006600;
-}
-
-.siteTable .bg2 {
- background-color:#CDD8FF;
- color:#6A5A00;
-}
-
-.monoTable {
- background-color:#565D82;
- font-family:monospace;
- font-size:10pt;
-}
-
-.monoTable .bg0 {
- background-color:#565D82;
- color:#FFFFFF;
-}
-
-.monoTable .bg1 {
- background-color:#F1F4FE;
- color:#006600;
-}
-
-.monoTable .bg2 {
- background-color:#CDD8FF;
- color:#6A5A00;
-}
-
-.themesMenu {
- display:block;
- margin:0;
-}
-
-.themesMenu table {
- background-color:#858654;
- font-family:Arial,Helvetica,sans-serif;
- font-size:0.7em;
- text-align:center;
-}
-
-.themesMenu .bg1 {
- background-color:#F1F4FE;
- color:#6A5A00;
- font-weight:bold;
-}
-
-.themesMenu .bg1 td {
- padding-top:2px;
- padding-bottom:2px;
- text-align:center;
-}
-
-.normText {
- font-family:Arial,Verdana,Geneva,Helvetica,sans-serif;
- font-size:0.96em;
- text-align:justify;
-}
-
-.normText a {
- font-family:Arial,Helvetica,sans-serif;
- font-size:11pt;
- text-align:justify;
- text-decoration:underline;
-}
-
-.normText a:link {color: #006600; text-decoration: underline;}
-.normText a:visited {color: #009900; text-decoration: underline;}
-.normText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-
-.demoText {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
- text-align:justify;
-}
-
-.demoText a {
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- text-decoration:underline;
-}
-
-.demoText a:link {color: #003300; text-decoration: underline;}
-.demoText a:visited {color: #003300; text-decoration: underline;}
-.demoText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-.demoTextBold {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:bold;
- color: #000000;
- text-align:justify;
-}
-
-.siteMap a {
- border: 2px solid #F1F4FE;
-}
-
-#fixedBack {
- background-image:url('../images/skin-01/fixed-back.gif');
- background-attachment:fixed;
-}
-
-.redNote {
- font-family:tahoma,arial,sans-serif;
- font-size:10pt;
- font-weight:bold;
- font-style:italic;
- color: #CC3300;
- margin-left:15px;
-}
-
-.divHeader {
- text-align:center;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.72em;
- padding:5px;
- color:#FFFFFF;
- border:0;
- background-color:#565D82;
-}
-
-.divDataLgt {
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:normal;
- font-size:0.7em;
- padding:5px;
- color:#6A5A00;
- background-color:#F1F4FE;
-}
-
-.divData {
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:normal;
- font-size:0.7em;
- padding:5px;
- color:#6A5A00;
- background-color:#CDD8FF;
-}
-
-.divData a {
- display:inline;
- font-size:1em;
- color:#6A5A00;
-}
-
-.codeBox {
- font-family:monospace,courier;
- font-size:9pt;
- font-weight:normal;
- color: #003300;
- background-color:#F8F8FF;
- border:3px double #565D82;
- padding:7px;
- margin-bottom:30px;
-}
-
-.dataArea {
- padding:0;
- border:4px double #565D82;
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
- line-height:140%;
-}
-
-.dataArea .subArea1 {
- padding:16px;
- background-color:#CDD8FF;
- color:#6A5A00;
-}
-
-.dataArea .subArea2 {
- padding:16px;
- background-color:#F1F4FE;
- color:#000066;
-}
-
-.dataArea .pseudoLink {
- display:inline;
- text-decoration:underline;
- color:#000000;
- font-size:10pt;
- font-weight:normal;
- cursor:pointer;
-}
-
-.dataArea .pseudoLinkReverse {
- display:inline;
- color:#FFFFFF;
- background-color:#565D82;
- font-size:9.4pt;
- font-weight:bolder;
- padding-left:4px;
- padding-right:4px;
-}
-
-.dataArea hr {
- height:1px;
- color:#565D82;
-}
-
-fieldset {
- display:block;
- background-color:#F1F4FE;
- border:2px dotted #565D82;
- margin-top:0;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-fieldset legend {
- color: #6A5A00;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-variant: small-caps;
- font-size:11pt;
- margin-top:10px;
- padding: .3ex .8ex;
- border:3px #565D82 double;
- font-weight: bold;
- background-color:#CDD8FF;
-}
-
-.bankHolsInner {
- display:block;
- background-color:#CDD8FF;
- text-align:center;
- margin:0 auto;
- border:#565D82 3px double;
- padding:0.8em;
-}
-
-.bankHolsTitle {
- font-family:Verdana,Arial,Helvetica,sans-serif;
- font-size:11pt;
- font-weight:bolder;
- color:#003300;
- margin-bottom:7px;
-}
-
-.hexRgbOuter {
- float:left;
- margin-top:7px;
- margin-right:20px;
-}
-
-.hexRgbInner {
- display:block;
- background-color:#CDD8FF;
- text-align:center;
- margin:0 auto;
- border:#565D82 3px double;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-.multiSearchOuter {
- text-align:center;
-}
-
-.multiSearchInner {
- width:440px;
- padding-left:10px;
- padding-right:10px;
- padding-bottom:10px;
- margin-left:auto;
- margin-right:auto;
- background-color:#CDD8FF;
- border:#565D82 3px double;
-}
-
-.multiSearchOuter table {
- width:400px;
- text-align:left;
- margin-left:auto;
- margin-right:auto;
-}
-
-.lineAcross1 {
- clear:both;
- display:block;
- background:url('../images/skin-01/line-horz-1.gif');
-}
-
-.lineAcross2 {
- clear:both;
- display:block;
- background:url('../images/skin-01/line-horz-2.gif');
-}
-
-.lineAcross3 {
- clear:both;
- display:block;
- background:url('../images/skin-01/line-horz-3.gif');
-}
-
-.lineAcross4 {
- clear:both;
- display:block;
- background:url('../images/skin-01/line-horz-4.gif');
-}
-
-.fancyLink {
- width:360px;
- text-align:justify;
- line-height:0.96em;
-}
-
-.fancyLink a {
- font-family:arial,helvetica,sans-serif;
- font-weight:normal;
- font-size:9pt;
- color:#990000;
- text-decoration:none;
-}
-
-.fancyLink em {
- font-size:9pt;
- font-family:tahoma,arial,helvetica,sans-serif;
- font-weight:bold;
- font-style:normal;
- text-transform:none;
- color:#006600;
- text-decoration:underline;
-}
-
-.fancyLink small {
- font-family:arial,helvetica,sans-serif;
- font-size:8pt;
- font-weight:normal;
- font-style:normal;
- color:#006600;
- text-decoration:underline;
-}
-
-.fancyLink .lineDown {
- background-color:#565D82;
-}
-
-.red {
- color:#FF0000;
-}
-
-.htmCode {
- color:#C00000;
- font-family:courier,monospace;
-}
-
-.cssCode {
- color:#0033FF;
- font-family:courier,monospace;
-}
-
-.green {
- color:#009933;
- font-family:courier,monospace;
-}
-
-.linksFieldset {
- width:50%;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-.bg0 {
- background-color:#858654;
-}
-
-.bg1 {
- background-color:#FFFFFF;
-}
-
-.bold {
- font-weight:bold;
-}
-
-.boldItalic {
- font-weight:bolder;
- font-style:italic;
-}
-
-.italic {
- font-style:italic;
-}
-
-.inputTitle {
- margin-top:8px;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
- color:#006600;
- text-transform:uppercase;
-}
-
-.editpadImage {
- display:inline;
- width:670px;
- border-left:2px solid #D2D2A5;
- border-top:2px solid #D2D2A5;
- border-right:2px dashed #CC0033;
- border-bottom:2px dashed #CC0033;
-}
-
-#xbitCounter {
- margin-top:7px;
- padding-top:2px;
- padding-bottom:2px;
- border: 1px solid #565D82;
- background-color:#F1F4FE;
-}
-
-a {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#006600;
-}
-
-.aiTable {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#006600;
-}
-
-.aiTable th {
- font-size:11pt;
- text-align:left;
-}
-
-.aiTable td {
- text-align:justify;
-}
-
-.lineDown {
- background-color:#006600;
-}
-
-.searchBox {
- background-color:#CDD8FF;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #6A5A00;
- border-right: 2px #666666 solid;
- border-bottom: 2px #666666 solid;
- border-top: 1px #cccccc solid;
- border-left: 1px #cccccc solid;
-}
-
-.searchBox .searchTitle {
- font-family:'Whimsy TT',fantasy,cursive;
- font-size:20pt;
- font-variant:small-caps;
- color:#6A5A00;
-}
-
-.buttonHi {
- background-color:#565D82;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonHi {
- width:80px;
- background-color:#565D82;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonLo {
- width:80px;
- background-color:#CDD8FF;
- color:#6A5A00;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.folderView {
- display:block;
- background-image:url('../images/skin-01/folder-2.gif');
-}
-
-.randOuter {
- clear:both;
-}
-
-.randList {
- display:block;
- width:100%;
- text-align:right;
- list-style-type:none;
- margin:0px;
- padding:0px;
- line-height:0px;
-}
-
-.randList li {
- display:block;
- float:left;
- width:68px;
- background-color:#CDD8FF;
- border-top:1px solid #333333;
- border-left:1px solid #333333;
- padding:3px;
- margin:0px;
-}
+/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */ + +.dummy { + font-family:verdana, arial, helvetica, sans-serif; +} + + +/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */ + +body { + margin:0px; + padding:0px; + background-color:#F1F4FE; + font-size: 100% !important; + line-height: normal !important; +} + +.headerArea { + height:120px; + margin:0px; + padding:0px; + line-height:60%; + text-align:center; + color:#FFFFFF; + background-color:#565D82; + background-image:url('../images/skin-01/theme-back.jpg'); +} + +.headerArea a { + color:#FFFFFF; +} + +.headerArea img { + margin-left:auto; + margin-right:auto; +} + +.h1 { + font-family: verdana,arial,helvetiva,sans-serif; + font-size:15pt; + font-weight:normal; + color:#003300; + border:3px #565D82 double; + padding-top:4px; + padding-bottom:6px; + width:60%; + margin:0 auto; + background-color:#CDD8FF; + text-align:center; +} + +.h2 { + margin-top:20px; + padding:0px; + font-family:"Comic Sans MS","VagRounded BT","Impress BT",cursive; + font-size:1.17em; + font-weight:normal; + color:#006600; +} + + +.h3 { + clear:both; + padding-top:16px; + padding-bottom:8px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 10pt; + color: #006600; +} + +.h3 span { + display:inline; + border-top: 1px #666666 solid; + border-bottom: 1px #666666 solid; + padding:0; + padding-top: 5px; + padding-bottom: 5px; + margin:0; +} + +.bestViewed { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:26px; + margin:0 auto; +} + +.pageMessage { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:16px; + margin:0 auto; + margin-bottom:30px; +} + +.footerArea { + clear:both; + width:100%; + text-align:center; + color:#FFFFFF; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.71em; + padding-top:0px; + background-color:#565D82; + background-image:url('../images/skin-01/theme-back.jpg'); +} + +.footerText { + padding-top:4px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; +} + +.footerText a { + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; + text-decoration:underline; +} + +.footerText a:link {color: #FFFFFF; text-decoration: underline;} +.footerText a:visited {color: #FFFFFF; text-decoration: underline;} +.footerText a:hover {color: #FFFF00; text-decoration: underline;} +.footerText a:focus {color: #FF0000; text-decoration: underline;} +.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;} + + +/* ======= UNIVERSAL MAIN-MENU STYLES ======= */ + + +.mainMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#565D82; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu li { + display:inline; +} + +.mainMenu a { + float:left; + width:90px; + color:#FFFFFF; + background-color:#565D82; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #FFFFFF; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #FFFFFF; + text-align:center; + font-size:9pt; + font-weight:bold; + color:#6A5A00; + background-color:#FFFFFF; + background-image:url('../images/skin-01/deadlink-back.gif'); +} + +.mainMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-01/hoverlink-back.gif'); +} + + +/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */ + + +.subMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#CDD8FF; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu li { + display:inline; +} + +.subMenu a { + float:left; + width:90px; + color:#6A5A00; + background-color:#CDD8FF; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #565D82; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #858654; + text-align:center; + color:#6A5A00; + background-color:#FFFFFF; + background-image:url('../images/skin-01/deadlink-back.gif'); + background-position: 0px -1px; +} + +.subMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-01/hoverlink-back.gif'); + background-position: 0px -1px; +} + + +/* ======= SITE TABLES/BOXES STYLES ======= */ + +.siteTable { + background-color:#565D82; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; +} + +.siteTable .bg0 { + background-color:#565D82; + color:#FFFFFF; +} + +.siteTable .bg1 { + background-color:#F1F4FE; + color:#006600; +} + +.siteTable .bg2 { + background-color:#CDD8FF; + color:#6A5A00; +} + +.monoTable { + background-color:#565D82; + font-family:monospace; + font-size:10pt; +} + +.monoTable .bg0 { + background-color:#565D82; + color:#FFFFFF; +} + +.monoTable .bg1 { + background-color:#F1F4FE; + color:#006600; +} + +.monoTable .bg2 { + background-color:#CDD8FF; + color:#6A5A00; +} + +.themesMenu { + display:block; + margin:0; +} + +.themesMenu table { + background-color:#858654; + font-family:Arial,Helvetica,sans-serif; + font-size:0.7em; + text-align:center; +} + +.themesMenu .bg1 { + background-color:#F1F4FE; + color:#6A5A00; + font-weight:bold; +} + +.themesMenu .bg1 td { + padding-top:2px; + padding-bottom:2px; + text-align:center; +} + +.normText { + font-family:Arial,Verdana,Geneva,Helvetica,sans-serif; + font-size:0.96em; + text-align:justify; +} + +.normText a { + font-family:Arial,Helvetica,sans-serif; + font-size:11pt; + text-align:justify; + text-decoration:underline; +} + +.normText a:link {color: #006600; text-decoration: underline;} +.normText a:visited {color: #009900; text-decoration: underline;} +.normText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + + +.demoText { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; + text-align:justify; +} + +.demoText a { + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + text-decoration:underline; +} + +.demoText a:link {color: #003300; text-decoration: underline;} +.demoText a:visited {color: #003300; text-decoration: underline;} +.demoText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + +.demoTextBold { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:bold; + color: #000000; + text-align:justify; +} + +.siteMap a { + border: 2px solid #F1F4FE; +} + +#fixedBack { + background-image:url('../images/skin-01/fixed-back.gif'); + background-attachment:fixed; +} + +.redNote { + font-family:tahoma,arial,sans-serif; + font-size:10pt; + font-weight:bold; + font-style:italic; + color: #CC3300; + margin-left:15px; +} + +.divHeader { + text-align:center; + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.72em; + padding:5px; + color:#FFFFFF; + border:0; + background-color:#565D82; +} + +.divDataLgt { + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-weight:normal; + font-size:0.7em; + padding:5px; + color:#6A5A00; + background-color:#F1F4FE; +} + +.divData { + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-weight:normal; + font-size:0.7em; + padding:5px; + color:#6A5A00; + background-color:#CDD8FF; +} + +.divData a { + display:inline; + font-size:1em; + color:#6A5A00; +} + +.codeBox { + font-family:monospace,courier; + font-size:9pt; + font-weight:normal; + color: #003300; + background-color:#F8F8FF; + border:3px double #565D82; + padding:7px; + margin-bottom:30px; +} + +.dataArea { + padding:0; + border:4px double #565D82; + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; + line-height:140%; +} + +.dataArea .subArea1 { + padding:16px; + background-color:#CDD8FF; + color:#6A5A00; +} + +.dataArea .subArea2 { + padding:16px; + background-color:#F1F4FE; + color:#000066; +} + +.dataArea .pseudoLink { + display:inline; + text-decoration:underline; + color:#000000; + font-size:10pt; + font-weight:normal; + cursor:pointer; +} + +.dataArea .pseudoLinkReverse { + display:inline; + color:#FFFFFF; + background-color:#565D82; + font-size:9.4pt; + font-weight:bolder; + padding-left:4px; + padding-right:4px; +} + +.dataArea hr { + height:1px; + color:#565D82; +} + +fieldset { + display:block; + background-color:#F1F4FE; + border:2px dotted #565D82; + margin-top:0; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +fieldset legend { + color: #6A5A00; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-variant: small-caps; + font-size:11pt; + margin-top:10px; + padding: .3ex .8ex; + border:3px #565D82 double; + font-weight: bold; + background-color:#CDD8FF; +} + +.bankHolsInner { + display:block; + background-color:#CDD8FF; + text-align:center; + margin:0 auto; + border:#565D82 3px double; + padding:0.8em; +} + +.bankHolsTitle { + font-family:Verdana,Arial,Helvetica,sans-serif; + font-size:11pt; + font-weight:bolder; + color:#003300; + margin-bottom:7px; +} + +.hexRgbOuter { + float:left; + margin-top:7px; + margin-right:20px; +} + +.hexRgbInner { + display:block; + background-color:#CDD8FF; + text-align:center; + margin:0 auto; + border:#565D82 3px double; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +.multiSearchOuter { + text-align:center; +} + +.multiSearchInner { + width:440px; + padding-left:10px; + padding-right:10px; + padding-bottom:10px; + margin-left:auto; + margin-right:auto; + background-color:#CDD8FF; + border:#565D82 3px double; +} + +.multiSearchOuter table { + width:400px; + text-align:left; + margin-left:auto; + margin-right:auto; +} + +.lineAcross1 { + clear:both; + display:block; + background:url('../images/skin-01/line-horz-1.gif'); +} + +.lineAcross2 { + clear:both; + display:block; + background:url('../images/skin-01/line-horz-2.gif'); +} + +.lineAcross3 { + clear:both; + display:block; + background:url('../images/skin-01/line-horz-3.gif'); +} + +.lineAcross4 { + clear:both; + display:block; + background:url('../images/skin-01/line-horz-4.gif'); +} + +.fancyLink { + width:360px; + text-align:justify; + line-height:0.96em; +} + +.fancyLink a { + font-family:arial,helvetica,sans-serif; + font-weight:normal; + font-size:9pt; + color:#990000; + text-decoration:none; +} + +.fancyLink em { + font-size:9pt; + font-family:tahoma,arial,helvetica,sans-serif; + font-weight:bold; + font-style:normal; + text-transform:none; + color:#006600; + text-decoration:underline; +} + +.fancyLink small { + font-family:arial,helvetica,sans-serif; + font-size:8pt; + font-weight:normal; + font-style:normal; + color:#006600; + text-decoration:underline; +} + +.fancyLink .lineDown { + background-color:#565D82; +} + +.red { + color:#FF0000; +} + +.htmCode { + color:#C00000; + font-family:courier,monospace; +} + +.cssCode { + color:#0033FF; + font-family:courier,monospace; +} + +.green { + color:#009933; + font-family:courier,monospace; +} + +.linksFieldset { + width:50%; + text-align:center; + margin-left:auto; + margin-right:auto; +} + +.bg0 { + background-color:#858654; +} + +.bg1 { + background-color:#FFFFFF; +} + +.bold { + font-weight:bold; +} + +.boldItalic { + font-weight:bolder; + font-style:italic; +} + +.italic { + font-style:italic; +} + +.inputTitle { + margin-top:8px; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; + color:#006600; + text-transform:uppercase; +} + +.editpadImage { + display:inline; + width:670px; + border-left:2px solid #D2D2A5; + border-top:2px solid #D2D2A5; + border-right:2px dashed #CC0033; + border-bottom:2px dashed #CC0033; +} + +#xbitCounter { + margin-top:7px; + padding-top:2px; + padding-bottom:2px; + border: 1px solid #565D82; + background-color:#F1F4FE; +} + +a { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#006600; +} + +.aiTable { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#006600; +} + +.aiTable th { + font-size:11pt; + text-align:left; +} + +.aiTable td { + text-align:justify; +} + +.lineDown { + background-color:#006600; +} + +.searchBox { + background-color:#CDD8FF; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #6A5A00; + border-right: 2px #666666 solid; + border-bottom: 2px #666666 solid; + border-top: 1px #cccccc solid; + border-left: 1px #cccccc solid; +} + +.searchBox .searchTitle { + font-family:'Whimsy TT',fantasy,cursive; + font-size:20pt; + font-variant:small-caps; + color:#6A5A00; +} + +.buttonHi { + background-color:#565D82; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonHi { + width:80px; + background-color:#565D82; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonLo { + width:80px; + background-color:#CDD8FF; + color:#6A5A00; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.folderView { + display:block; + background-image:url('../images/skin-01/folder-2.gif'); +} + +.randOuter { + clear:both; +} + +.randList { + display:block; + width:100%; + text-align:right; + list-style-type:none; + margin:0px; + padding:0px; + line-height:0px; +} + +.randList li { + display:block; + float:left; + width:68px; + background-color:#CDD8FF; + border-top:1px solid #333333; + border-left:1px solid #333333; + padding:3px; + margin:0px; +} diff --git a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-2.css b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-2.css index 8a4baf7b..ff7192fa 100644 --- a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-2.css +++ b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-2.css @@ -1,746 +1,746 @@ -/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */
-
-.dummy {
- font-family:verdana, arial, helvetica, sans-serif;
-}
-
-
-/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */
-
-body {
- margin:0px;
- padding:0px;
- background-color:#FFFFF3;
- font-size: 100% !important;
- line-height: normal !important;
-}
-
-.headerArea {
- height:120px;
- margin:0px;
- padding:0px;
- line-height:60%;
- text-align:center;
- color:#F8F8EE;
- background-color:#707154;
- background-image:url('../images/skin-02/theme-back.jpg');
-}
-
-.headerArea a {
- color:#F8F8EE;
-}
-
-.headerArea img {
- margin-left:auto;
- margin-right:auto;
-}
-
-.h1 {
- font-family: verdana,arial,helvetiva,sans-serif;
- font-size:15pt;
- font-weight:normal;
- color:#373C93;
- border:3px #838367 double;
- padding-top:4px;
- padding-bottom:6px;
- width:60%;
- margin:0 auto;
- background-color:#F7F8D9;
- text-align:center;
-}
-
-.h2 {
- margin-top:20px;
- padding:0px;
- font-family:"Comic Sans MS","VagRounded BT","Impress BT",cursive;
- font-size:1.17em;
- font-weight:normal;
- color:#373C93;
-}
-
-
-.h3 {
- clear:both;
- padding-top:16px;
- padding-bottom:8px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 10pt;
- color: #373C93;
-}
-
-.h3 span {
- display:inline;
- border-top: 1px #666666 solid;
- border-bottom: 1px #666666 solid;
- padding:0;
- padding-top: 5px;
- padding-bottom: 5px;
- margin:0;
-}
-
-.bestViewed {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:26px;
- margin:0 auto;
-}
-
-.pageMessage {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:16px;
- margin:0 auto;
- margin-bottom:30px;
-}
-
-.footerArea {
- clear:both;
- width:100%;
- text-align:center;
- color:#F8F8EE;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.71em;
- padding-top:0px;
- background-color:#707154;
- background-image:url('../images/skin-02/theme-back.jpg');
-}
-
-.footerText {
- padding-top:4px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#F8F8EE;
-}
-
-.footerText a {
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#F8F8EE;
- text-decoration:underline;
-}
-
-.footerText a:link {color: #F8F8EE; text-decoration: underline;}
-.footerText a:visited {color: #F8F8EE; text-decoration: underline;}
-.footerText a:hover {color: #FFFF00; text-decoration: underline;}
-.footerText a:focus {color: #FF0000; text-decoration: underline;}
-.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;}
-
-
-/* ======= UNIVERSAL MAIN-MENU STYLES ======= */
-
-
-.mainMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#707154;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu li {
- display:inline;
-}
-
-.mainMenu a {
- float:left;
- width:90px;
- color:#F8F8EE;
- background-color:#707154;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #F7F8D9;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #F7F8D9;
- text-align:center;
- font-size:9pt;
- font-weight:bold;
- color:#707154;
- background-color:#F8F8EE;
- background-image:url('../images/skin-02/deadlink-back.gif');
-}
-
-.mainMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-02/hoverlink-back.gif');
-}
-
-
-/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */
-
-
-.subMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#F7F8D9;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu li {
- display:inline;
-}
-
-.subMenu a {
- float:left;
- width:90px;
- color:#373C93;
- background-color:#F7F8D9;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #707154;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #707154;
- text-align:center;
- color:#707154;
- background-color:#F8F8EE;
- background-image:url('../images/skin-02/deadlink-back.gif');
- background-position: 0px -1px;
-}
-
-.subMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-02/hoverlink-back.gif');
- background-position: 0px -1px;
-}
-
-
-/* ======= SITE TABLES/BOXES STYLES ======= */
-
-.siteTable {
- background-color:#707154;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
-}
-
-.siteTable .bg0 {
- background-color:#707154;
- color:#F8F8EE;
-}
-
-.siteTable .bg1 {
- background-color:#FFFFF3;
- color:#373C93;
-}
-
-.siteTable .bg2 {
- background-color:#F7F8D9;
- color:#707154;
-}
-
-.monoTable {
- background-color:#707154;
- font-family:monospace;
- font-size:10pt;
-}
-
-.monoTable .bg0 {
- background-color:#707154;
- color:#F8F8EE;
-}
-
-.monoTable .bg1 {
- background-color:#FFFFF3;
- color:#373C93;
-}
-
-.monoTable .bg2 {
- background-color:#F7F8D9;
- color:#707154;
-}
-
-.themesMenu {
- display:block;
- margin:0;
-}
-
-.themesMenu table {
- background-color:#838367;
- font-family:Arial,Helvetica,sans-serif;
- font-size:0.7em;
- text-align:center;
-}
-
-.themesMenu .bg1 td {
- padding-top:2px;
- padding-bottom:2px;
- text-align:center;
-}
-
-.divHeader {
- text-align:center;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.72em;
- padding:5px;
- color:#F8F8EE;
- border:0;
- background-color:#707154;
-}
-
-.divData {
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:normal;
- font-size:0.7em;
- padding:5px;
- color:#707154;
- background-color:#F7F8D9;
-}
-
-.divData a {
- display:inline;
- font-size:1em;
- color:#707154;
-}
-
-.codeBox {
- font-family:monospace,courier;
- font-size:9pt;
- font-weight:normal;
- color: #707154;
- background-color:#FDFDFA;
- border:3px double #838367;
- padding:7px;
- margin-bottom:30px;
-}
-
-.dataArea {
- padding:0;
- border:4px double #838367;
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
- line-height:140%;
-}
-
-.dataArea .subArea1 {
- padding:16px;
- background-color:#F7F8D9;
- color:#000033;
-}
-
-.dataArea .subArea2 {
- padding:16px;
- background-color:#FFFFF3;
- color:#000066;
-}
-
-.dataArea .pseudoLink {
- display:inline;
- text-decoration:underline;
- color:#000000;
- font-size:10pt;
- font-weight:normal;
- cursor:pointer;
-}
-
-.dataArea .pseudoLinkReverse {
- display:inline;
- color:#F8F8EE;
- background-color:#707154;
- font-size:9.4pt;
- font-weight:bolder;
- padding-left:4px;
- padding-right:4px;
-}
-
-.dataArea hr {
- height:1px;
- color:#707154;
-}
-
-fieldset {
- display:block;
- background-color:#FFFFF3;
- border:2px dotted #838367;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-fieldset legend {
- color: #373C93;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-variant: small-caps;
- font-size:11pt;
- margin-top:10px;
- padding: .3ex .8ex;
- border:3px #838367 double;
- font-weight: bold;
- background-color:#F7F8D9;
-}
-
-.bankHolsInner {
- display:block;
- background-color:#F7F8D9;
- text-align:center;
- margin:0 auto;
- border:#838367 3px double;
- padding:0.8em;
-}
-
-.bankHolsTitle {
- font-family:Verdana,Arial,Helvetica,sans-serif;
- font-size:11pt;
- font-weight:bolder;
- color:#373C93;
- margin-bottom:7px;
-}
-
-.hexRgbOuter {
- float:left;
- margin-top:7px;
- margin-right:20px;
-}
-
-.hexRgbInner {
- display:block;
- background-color:#F7F8D9;
- text-align:center;
- margin:0 auto;
- border:#838367 3px double;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-.multiSearchOuter {
- text-align:center;
-}
-
-.multiSearchInner {
- width:440px;
- padding-left:10px;
- padding-right:10px;
- padding-bottom:10px;
- margin-left:auto;
- margin-right:auto;
- background-color:#F7F8D9;
- border:#838367 3px double;
-}
-
-.multiSearchOuter table {
- width:400px;
- text-align:left;
- margin-left:auto;
- margin-right:auto;
-}
-
-.lineAcross1 {
- clear:both;
- display:block;
- background:url('../images/skin-02/line-horz-1.gif');
-}
-
-.lineAcross2 {
- clear:both;
- display:block;
- background:url('../images/skin-02/line-horz-2.gif');
-}
-
-.lineAcross3 {
- clear:both;
- display:block;
- background:url('../images/skin-02/line-horz-3.gif');
-}
-
-.lineAcross4 {
- clear:both;
- display:block;
- background:url('../images/skin-02/line-horz-4.gif');
-}
-
-.normText {
- font-family:Arial,Verdana,Geneva,Helvetica,sans-serif;
- font-size:0.96em;
- text-align:justify;
- color:#0C0C0C;
-}
-
-.normText a {
- font-family:Arial,Helvetica,sans-serif;
- font-size:11pt;
- text-align:justify;
- text-decoration:underline;
-}
-
-.normText a:link {color: #373C93; text-decoration: underline;}
-.normText a:visited {color: #009900; text-decoration: underline;}
-.normText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-
-.demoText {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
- text-align:justify;
-}
-
-.demoText a {
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- text-decoration:underline;
-}
-
-.demoText a:link {color: #707154; text-decoration: underline;}
-.demoText a:visited {color: #707154; text-decoration: underline;}
-.demoText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-.demoTextBold {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:bold;
- color: #000000;
- text-align:justify;
-}
-
-.siteMap a {
- border: 2px solid #FFFFF3;
-}
-
-#fixedBack {
- background-image:url('../images/skin-02/fixed-back.gif');
- background-attachment:fixed;
-}
-
-.redNote {
- font-family:tahoma,arial,sans-serif;
- font-size:10pt;
- font-weight:bold;
- font-style:italic;
- color: #CC3300;
- margin-left:15px;
-}
-
-.fancyLink {
- width:360px;
- text-align:justify;
- line-height:0.96em;
-}
-
-.fancyLink a {
- font-family:arial,helvetica,sans-serif;
- font-weight:normal;
- font-size:9pt;
- color:#990000;
- text-decoration:none;
-}
-
-.fancyLink em {
- font-size:9pt;
- font-family:tahoma,arial,helvetica,sans-serif;
- font-weight:bold;
- font-style:normal;
- text-transform:none;
- color:#373C93;
- text-decoration:underline;
-}
-
-.fancyLink small {
- font-family:arial,helvetica,sans-serif;
- font-size:8pt;
- font-weight:normal;
- font-style:normal;
- color:#373C93;
- text-decoration:underline;
-}
-
-.fancyLink .lineDown {
- background-color:#838367;
-}
-
-.red {
- color:#FF0000;
-}
-
-.htmCode {
- color:#C00000;
- font-family:courier,monospace;
-}
-
-.cssCode {
- color:#0033FF;
- font-family:courier,monospace;
-}
-
-.green {
- color:#009933;
- font-family:courier,monospace;
-}
-
-.linksFieldset {
- width:50%;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-.bg0 {
- background-color:#838367;
-}
-
-.bg1 {
- background-color:#F8F8EE;
-}
-
-.bold {
- font-weight:bold;
-}
-
-.boldItalic {
- font-weight:bolder;
- font-style:italic;
-}
-
-.italic {
- font-style:italic;
-}
-
-.inputTitle {
- margin-top:8px;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
- color:#373C93;
- text-transform:uppercase;
-}
-
-.editpadImage {
- display:inline;
- width:670px;
- border-left:2px solid #FFFFF3;
- border-top:2px solid #FFFFF3;
- border-right:2px dashed #CC0033;
- border-bottom:2px dashed #CC0033;
-}
-
-#xbitCounter {
- margin-top:7px;
- padding-top:2px;
- padding-bottom:2px;
- border: 1px solid #838367;
- background-color:#FFFFF3;
-}
-
-a {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#373C93;
-}
-
-.aiTable {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#373C93;
-}
-
-.aiTable th {
- font-size:11pt;
- text-align:left;
-}
-
-.aiTable td {
- text-align:justify;
-}
-
-.lineDown {
- background-color:#373C93;
-}
-
-.searchBox {
- background-color:#F7F8D9;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #707154;
- border-right: 2px #666666 solid;
- border-bottom: 2px #666666 solid;
- border-top: 1px #cccccc solid;
- border-left: 1px #cccccc solid;
-}
-
-.searchBox .searchTitle {
- font-family:'Whimsy TT',fantasy,cursive;
- font-size:20pt;
- font-variant:small-caps;
- color:#707154;
-}
-
-.buttonHi {
- background-color:#707154;
- color:#F8F8EE;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonHi {
- width:80px;
- background-color:#707154;
- color:#F8F8EE;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonLo {
- width:80px;
- background-color:#F7F8D9;
- color:#707154;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.folderView {
- display:block;
- background-image:url('../images/skin-02/folder-2.gif');
-}
+/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */ + +.dummy { + font-family:verdana, arial, helvetica, sans-serif; +} + + +/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */ + +body { + margin:0px; + padding:0px; + background-color:#FFFFF3; + font-size: 100% !important; + line-height: normal !important; +} + +.headerArea { + height:120px; + margin:0px; + padding:0px; + line-height:60%; + text-align:center; + color:#F8F8EE; + background-color:#707154; + background-image:url('../images/skin-02/theme-back.jpg'); +} + +.headerArea a { + color:#F8F8EE; +} + +.headerArea img { + margin-left:auto; + margin-right:auto; +} + +.h1 { + font-family: verdana,arial,helvetiva,sans-serif; + font-size:15pt; + font-weight:normal; + color:#373C93; + border:3px #838367 double; + padding-top:4px; + padding-bottom:6px; + width:60%; + margin:0 auto; + background-color:#F7F8D9; + text-align:center; +} + +.h2 { + margin-top:20px; + padding:0px; + font-family:"Comic Sans MS","VagRounded BT","Impress BT",cursive; + font-size:1.17em; + font-weight:normal; + color:#373C93; +} + + +.h3 { + clear:both; + padding-top:16px; + padding-bottom:8px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 10pt; + color: #373C93; +} + +.h3 span { + display:inline; + border-top: 1px #666666 solid; + border-bottom: 1px #666666 solid; + padding:0; + padding-top: 5px; + padding-bottom: 5px; + margin:0; +} + +.bestViewed { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:26px; + margin:0 auto; +} + +.pageMessage { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:16px; + margin:0 auto; + margin-bottom:30px; +} + +.footerArea { + clear:both; + width:100%; + text-align:center; + color:#F8F8EE; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.71em; + padding-top:0px; + background-color:#707154; + background-image:url('../images/skin-02/theme-back.jpg'); +} + +.footerText { + padding-top:4px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#F8F8EE; +} + +.footerText a { + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#F8F8EE; + text-decoration:underline; +} + +.footerText a:link {color: #F8F8EE; text-decoration: underline;} +.footerText a:visited {color: #F8F8EE; text-decoration: underline;} +.footerText a:hover {color: #FFFF00; text-decoration: underline;} +.footerText a:focus {color: #FF0000; text-decoration: underline;} +.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;} + + +/* ======= UNIVERSAL MAIN-MENU STYLES ======= */ + + +.mainMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#707154; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu li { + display:inline; +} + +.mainMenu a { + float:left; + width:90px; + color:#F8F8EE; + background-color:#707154; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #F7F8D9; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #F7F8D9; + text-align:center; + font-size:9pt; + font-weight:bold; + color:#707154; + background-color:#F8F8EE; + background-image:url('../images/skin-02/deadlink-back.gif'); +} + +.mainMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-02/hoverlink-back.gif'); +} + + +/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */ + + +.subMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#F7F8D9; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu li { + display:inline; +} + +.subMenu a { + float:left; + width:90px; + color:#373C93; + background-color:#F7F8D9; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #707154; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #707154; + text-align:center; + color:#707154; + background-color:#F8F8EE; + background-image:url('../images/skin-02/deadlink-back.gif'); + background-position: 0px -1px; +} + +.subMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-02/hoverlink-back.gif'); + background-position: 0px -1px; +} + + +/* ======= SITE TABLES/BOXES STYLES ======= */ + +.siteTable { + background-color:#707154; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; +} + +.siteTable .bg0 { + background-color:#707154; + color:#F8F8EE; +} + +.siteTable .bg1 { + background-color:#FFFFF3; + color:#373C93; +} + +.siteTable .bg2 { + background-color:#F7F8D9; + color:#707154; +} + +.monoTable { + background-color:#707154; + font-family:monospace; + font-size:10pt; +} + +.monoTable .bg0 { + background-color:#707154; + color:#F8F8EE; +} + +.monoTable .bg1 { + background-color:#FFFFF3; + color:#373C93; +} + +.monoTable .bg2 { + background-color:#F7F8D9; + color:#707154; +} + +.themesMenu { + display:block; + margin:0; +} + +.themesMenu table { + background-color:#838367; + font-family:Arial,Helvetica,sans-serif; + font-size:0.7em; + text-align:center; +} + +.themesMenu .bg1 td { + padding-top:2px; + padding-bottom:2px; + text-align:center; +} + +.divHeader { + text-align:center; + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.72em; + padding:5px; + color:#F8F8EE; + border:0; + background-color:#707154; +} + +.divData { + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-weight:normal; + font-size:0.7em; + padding:5px; + color:#707154; + background-color:#F7F8D9; +} + +.divData a { + display:inline; + font-size:1em; + color:#707154; +} + +.codeBox { + font-family:monospace,courier; + font-size:9pt; + font-weight:normal; + color: #707154; + background-color:#FDFDFA; + border:3px double #838367; + padding:7px; + margin-bottom:30px; +} + +.dataArea { + padding:0; + border:4px double #838367; + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; + line-height:140%; +} + +.dataArea .subArea1 { + padding:16px; + background-color:#F7F8D9; + color:#000033; +} + +.dataArea .subArea2 { + padding:16px; + background-color:#FFFFF3; + color:#000066; +} + +.dataArea .pseudoLink { + display:inline; + text-decoration:underline; + color:#000000; + font-size:10pt; + font-weight:normal; + cursor:pointer; +} + +.dataArea .pseudoLinkReverse { + display:inline; + color:#F8F8EE; + background-color:#707154; + font-size:9.4pt; + font-weight:bolder; + padding-left:4px; + padding-right:4px; +} + +.dataArea hr { + height:1px; + color:#707154; +} + +fieldset { + display:block; + background-color:#FFFFF3; + border:2px dotted #838367; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +fieldset legend { + color: #373C93; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-variant: small-caps; + font-size:11pt; + margin-top:10px; + padding: .3ex .8ex; + border:3px #838367 double; + font-weight: bold; + background-color:#F7F8D9; +} + +.bankHolsInner { + display:block; + background-color:#F7F8D9; + text-align:center; + margin:0 auto; + border:#838367 3px double; + padding:0.8em; +} + +.bankHolsTitle { + font-family:Verdana,Arial,Helvetica,sans-serif; + font-size:11pt; + font-weight:bolder; + color:#373C93; + margin-bottom:7px; +} + +.hexRgbOuter { + float:left; + margin-top:7px; + margin-right:20px; +} + +.hexRgbInner { + display:block; + background-color:#F7F8D9; + text-align:center; + margin:0 auto; + border:#838367 3px double; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +.multiSearchOuter { + text-align:center; +} + +.multiSearchInner { + width:440px; + padding-left:10px; + padding-right:10px; + padding-bottom:10px; + margin-left:auto; + margin-right:auto; + background-color:#F7F8D9; + border:#838367 3px double; +} + +.multiSearchOuter table { + width:400px; + text-align:left; + margin-left:auto; + margin-right:auto; +} + +.lineAcross1 { + clear:both; + display:block; + background:url('../images/skin-02/line-horz-1.gif'); +} + +.lineAcross2 { + clear:both; + display:block; + background:url('../images/skin-02/line-horz-2.gif'); +} + +.lineAcross3 { + clear:both; + display:block; + background:url('../images/skin-02/line-horz-3.gif'); +} + +.lineAcross4 { + clear:both; + display:block; + background:url('../images/skin-02/line-horz-4.gif'); +} + +.normText { + font-family:Arial,Verdana,Geneva,Helvetica,sans-serif; + font-size:0.96em; + text-align:justify; + color:#0C0C0C; +} + +.normText a { + font-family:Arial,Helvetica,sans-serif; + font-size:11pt; + text-align:justify; + text-decoration:underline; +} + +.normText a:link {color: #373C93; text-decoration: underline;} +.normText a:visited {color: #009900; text-decoration: underline;} +.normText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + + +.demoText { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; + text-align:justify; +} + +.demoText a { + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + text-decoration:underline; +} + +.demoText a:link {color: #707154; text-decoration: underline;} +.demoText a:visited {color: #707154; text-decoration: underline;} +.demoText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + +.demoTextBold { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:bold; + color: #000000; + text-align:justify; +} + +.siteMap a { + border: 2px solid #FFFFF3; +} + +#fixedBack { + background-image:url('../images/skin-02/fixed-back.gif'); + background-attachment:fixed; +} + +.redNote { + font-family:tahoma,arial,sans-serif; + font-size:10pt; + font-weight:bold; + font-style:italic; + color: #CC3300; + margin-left:15px; +} + +.fancyLink { + width:360px; + text-align:justify; + line-height:0.96em; +} + +.fancyLink a { + font-family:arial,helvetica,sans-serif; + font-weight:normal; + font-size:9pt; + color:#990000; + text-decoration:none; +} + +.fancyLink em { + font-size:9pt; + font-family:tahoma,arial,helvetica,sans-serif; + font-weight:bold; + font-style:normal; + text-transform:none; + color:#373C93; + text-decoration:underline; +} + +.fancyLink small { + font-family:arial,helvetica,sans-serif; + font-size:8pt; + font-weight:normal; + font-style:normal; + color:#373C93; + text-decoration:underline; +} + +.fancyLink .lineDown { + background-color:#838367; +} + +.red { + color:#FF0000; +} + +.htmCode { + color:#C00000; + font-family:courier,monospace; +} + +.cssCode { + color:#0033FF; + font-family:courier,monospace; +} + +.green { + color:#009933; + font-family:courier,monospace; +} + +.linksFieldset { + width:50%; + text-align:center; + margin-left:auto; + margin-right:auto; +} + +.bg0 { + background-color:#838367; +} + +.bg1 { + background-color:#F8F8EE; +} + +.bold { + font-weight:bold; +} + +.boldItalic { + font-weight:bolder; + font-style:italic; +} + +.italic { + font-style:italic; +} + +.inputTitle { + margin-top:8px; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; + color:#373C93; + text-transform:uppercase; +} + +.editpadImage { + display:inline; + width:670px; + border-left:2px solid #FFFFF3; + border-top:2px solid #FFFFF3; + border-right:2px dashed #CC0033; + border-bottom:2px dashed #CC0033; +} + +#xbitCounter { + margin-top:7px; + padding-top:2px; + padding-bottom:2px; + border: 1px solid #838367; + background-color:#FFFFF3; +} + +a { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#373C93; +} + +.aiTable { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#373C93; +} + +.aiTable th { + font-size:11pt; + text-align:left; +} + +.aiTable td { + text-align:justify; +} + +.lineDown { + background-color:#373C93; +} + +.searchBox { + background-color:#F7F8D9; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #707154; + border-right: 2px #666666 solid; + border-bottom: 2px #666666 solid; + border-top: 1px #cccccc solid; + border-left: 1px #cccccc solid; +} + +.searchBox .searchTitle { + font-family:'Whimsy TT',fantasy,cursive; + font-size:20pt; + font-variant:small-caps; + color:#707154; +} + +.buttonHi { + background-color:#707154; + color:#F8F8EE; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonHi { + width:80px; + background-color:#707154; + color:#F8F8EE; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonLo { + width:80px; + background-color:#F7F8D9; + color:#707154; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.folderView { + display:block; + background-image:url('../images/skin-02/folder-2.gif'); +} diff --git a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-3.css b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-3.css index 2509c6b9..f69e640f 100644 --- a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-3.css +++ b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-3.css @@ -1,752 +1,752 @@ - /* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */
-
-.dummy {
- font-family:verdana, arial, helvetica, sans-serif;
-}
-
-
-/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */
-
-body {
- margin:0px;
- padding:0px;
- background-color:#FEFEFE;
- font-size: 100% !important;
- line-height: normal !important;
-}
-
-.headerArea {
- height:120px;
- margin:0px;
- padding:0px;
- line-height:60%;
- text-align:center;
- color:#FFFFFF;
- background-color:#333333;
- background-image:url('../images/skin-03/theme-back.jpg');
-}
-
-.headerArea a {
- color:#FFFFFF;
-}
-
-.headerArea img {
- margin-left:auto;
- margin-right:auto;
-}
-
-.h1 {
- font-family: verdana,arial,helvetiva,sans-serif;
- font-size:15pt;
- font-weight:normal;
- color:#000000;
- border:3px #333333 double;
- padding-top:4px;
- padding-bottom:6px;
- width:60%;
- margin:0 auto;
- background-color:#ECECEC;
- text-align:center;
-}
-
-.h2 {
- margin-top:20px;
- padding:0px;
- font-family:Arial,Helvetica,sans-serif;
- font-size:1.17em;
- font-weight:normal;
- color:#333333;
-}
-
-
-.h3 {
- clear:both;
- padding-top:16px;
- padding-bottom:8px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 10pt;
- color: #000066;
-}
-
-.h3 span {
- display:inline;
- border-top: 1px #666666 solid;
- border-bottom: 1px #666666 solid;
- padding:0;
- padding-top: 5px;
- padding-bottom: 5px;
- margin:0;
-}
-
-.bestViewed {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:26px;
- margin:0 auto;
-}
-
-.pageMessage {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:16px;
- margin:0 auto;
- margin-bottom:30px;
-}
-
-.footerArea {
- clear:both;
- width:100%;
- text-align:center;
- color:#000000;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.71em;
- padding-top:0px;
- background-color:#333333;
- background-image:url('../images/skin-03/theme-back.jpg');
-}
-
-.footerText {
- padding-top:4px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
-}
-
-.footerText a {
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
- text-decoration:underline;
-}
-
-.footerText a:link {color: #FFFFFF; text-decoration: underline;}
-.footerText a:visited {color: #FFFFFF; text-decoration: underline;}
-.footerText a:hover {color: #FFFF00; text-decoration: underline;}
-.footerText a:focus {color: #FF0000; text-decoration: underline;}
-.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;}
-
-
-/* ======= UNIVERSAL MAIN-MENU STYLES ======= */
-
-
-.mainMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#333333;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu li {
- display:inline;
-}
-
-.mainMenu a {
- float:left;
- width:90px;
- color:#FFFFFF;
- background-color:#333333;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #FFFFFF;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #FFFFFF;
- text-align:center;
- font-size:9pt;
- font-weight:bold;
- color:#000000;
- background-color:#FFFFFF;
- background-image:url('../images/skin-03/deadlink-back.gif');
-}
-
-.mainMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-03/hoverlink-back.gif');
-}
-
-
-/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */
-
-
-.subMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#ECECEC;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu li {
- display:inline;
-}
-
-.subMenu a {
- float:left;
- width:90px;
- color:#000000;
- background-color:#E8E8E8;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #333333;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #333333;
- text-align:center;
- color:#000000;
- background-color:#FFFFFF;
- background-image:url('../images/skin-03/deadlink-back.gif');
- background-position: 0px -1px;
-}
-
-.subMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-03/hoverlink-back.gif');
- background-position: 0px -1px;
-}
-
-
-/* ======= SITE TABLES/BOXES STYLES ======= */
-
-.siteTable {
- background-color:#333333;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
-}
-
-.siteTable .bg0 {
- background-color:#333333;
- color:#FFFFFF;
-}
-
-.siteTable .bg1 {
- background-color:#FEFEFE;
- color:#006600;
-}
-
-.siteTable .bg2 {
- background-color:#E8E8E8;
- color:#000000;
-}
-
-.monoTable {
- background-color:#333333;
- font-family:monospace;
- font-size:10pt;
-}
-
-.monoTable .bg0 {
- background-color:#333333;
- color:#FFFFFF;
-}
-
-.monoTable .bg1 {
- background-color:#FEFEFE;
- color:#006600;
-}
-
-.monoTable .bg2 {
- background-color:#E8E8E8;
- color:#000000;
-}
-
-.themesMenu {
- display:block;
- margin:0;
-}
-
-.themesMenu table {
- background-color:#838367;
- font-family:Arial,Helvetica,sans-serif;
- font-size:0.7em;
- text-align:center;
-}
-
-.themesMenu .bg1 {
- background-color:#FFFFFF;
- color:#006600;
- font-weight:bold;
-}
-
-.themesMenu .bg1 td {
- padding-top:2px;
- padding-bottom:2px;
- text-align:center;
-}
-
-.normText {
- font-family:Times,'Times New Roman',Palatino,serif;
- font-size:0.96em;
- text-align:justify;
-}
-
-.normText a {
- font-family:Arial,Helvetica,sans-serif;
- font-size:11pt;
- text-align:justify;
- text-decoration:underline;
-}
-
-.normText a:link {color: #006600; text-decoration: underline;}
-.normText a:visited {color: #009900; text-decoration: underline;}
-.normText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-
-.demoText {
- font-family:Times,'Times New Roman',Palatino,serif;
- font-size:0.85em;
- font-weight:normal;
- color: #000000;
- text-align:justify;
-}
-
-.demoText a {
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- text-decoration:underline;
-}
-
-.demoText a:link {color: #003300; text-decoration: underline;}
-.demoText a:visited {color: #003300; text-decoration: underline;}
-.demoText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-.demoTextBold {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:bold;
- color: #000000;
- text-align:justify;
-}
-
-.divHeader {
- text-align:center;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.72em;
- padding:5px;
- color:#FFFFFF;
- border:0;
- background-color:#333333;
-}
-
-.divData {
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:normal;
- font-size:0.7em;
- padding:5px;
- color:#000000;
- background-color:#E8E8E8;
-}
-
-.divData a {
- display:inline;
- font-size:1em;
- color:#000000;
-}
-
-.codeBox {
- font-family:monospace,courier;
- font-size:9pt;
- font-weight:normal;
- color: #000000;
- background-color:#ECECEC;
- border:3px double #333333;
- padding:7px;
- margin-bottom:30px;
-}
-
-.dataArea {
- padding:0;
- border:4px double #333333;
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
- line-height:140%;
-}
-
-.dataArea .subArea1 {
- padding:16px;
- background-color:#E8E8E8;
- color:#000033;
-}
-
-.dataArea .subArea2 {
- padding:16px;
- background-color:#FEFEFE;
- color:#000066;
-}
-
-.dataArea .pseudoLink {
- display:inline;
- text-decoration:underline;
- color:#000000;
- font-size:10pt;
- font-weight:normal;
- cursor:pointer;
-}
-
-.dataArea .pseudoLinkReverse {
- display:inline;
- color:#FFFFFF;
- background-color:#333333;
- font-size:9.4pt;
- font-weight:bolder;
- padding-left:4px;
- padding-right:4px;
-}
-
-.dataArea hr {
- height:1px;
- color:#48486E;
-}
-
-fieldset {
- display:block;
- background-color:#FFFFFF;
- border:2px dotted #333333;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-
-fieldset legend {
- color: #000000;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-variant: small-caps;
- font-size:11pt;
- margin-top:10px;
- padding: .3ex .8ex;
- border:3px #333333 double;
- font-weight: bold;
- background-color:#ECECEC;
-}
-
-.bankHolsInner {
- display:block;
- background-color:#ECECEC;
- text-align:center;
- margin:0 auto;
- border:#333333 3px double;
- padding:0.8em;
-}
-
-.bankHolsTitle {
- font-family:Verdana,Arial,Helvetica,sans-serif;
- font-size:11pt;
- font-weight:bolder;
- color:#000000;
- margin-bottom:7px;
-}
-
-.hexRgbOuter {
- float:left;
- margin-top:7px;
- margin-right:20px;
-}
-
-.hexRgbInner {
- display:block;
- background-color:#ECECEC;
- text-align:center;
- margin:0 auto;
- border:#333333 3px double;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-.multiSearchOuter {
- text-align:center;
-}
-
-.multiSearchInner {
- width:440px;
- padding-left:10px;
- padding-right:10px;
- padding-bottom:10px;
- margin-left:auto;
- margin-right:auto;
- background-color:#ECECEC;
- border:#333333 3px double;
-}
-
-.multiSearchOuter table {
- width:400px;
- text-align:left;
- margin-left:auto;
- margin-right:auto;
-}
-
-.lineAcross1 {
- clear:both;
- display:block;
- background:url('../images/skin-03/line-horz-1.gif');
-}
-
-.lineAcross2 {
- clear:both;
- display:block;
- background:url('../images/skin-03/line-horz-2.gif');
-}
-
-.lineAcross3 {
- clear:both;
- display:block;
- background:url('../images/skin-03/line-horz-3.gif');
-}
-
-.lineAcross4 {
- clear:both;
- display:block;
- background:url('../images/skin-03/line-horz-4.gif');
-}
-
-.siteMap a {
- border: 2px solid #FEFEFE;
-}
-
-#fixedBack {
- background-image:url('../images/skin-03/fixed-back.gif');
- background-attachment:fixed;
-}
-
-.redNote {
- font-family:tahoma,arial,sans-serif;
- font-size:10pt;
- font-weight:bold;
- font-style:italic;
- color: #333333;
- margin-left:15px;
-}
-
-.fancyLink {
- width:360px;
- text-align:justify;
- line-height:0.96em;
-}
-
-.fancyLink a {
- font-family:arial,helvetica,sans-serif;
- font-weight:normal;
- font-size:9pt;
- color:#666666;
- text-decoration:none;
-}
-
-.fancyLink em {
- font-size:9pt;
- font-family:tahoma,arial,helvetica,sans-serif;
- font-weight:bold;
- font-style:normal;
- text-transform:none;
- color:#333333;
- text-decoration:underline;
-}
-
-.fancyLink small {
- font-family:arial,helvetica,sans-serif;
- font-size:8pt;
- font-weight:normal;
- font-style:normal;
- color:#333333;
- text-decoration:underline;
-}
-
-.fancyLink .lineDown {
- background-color:#333333;
-}
-
-.red {
- color:#FF0000;
-}
-
-.htmCode {
- color:#C00000;
- font-family:courier,monospace;
-}
-
-.cssCode {
- color:#0033FF;
- font-family:courier,monospace;
-}
-
-.green {
- color:#009933;
- font-family:courier,monospace;
-}
-
-.linksFieldset {
- width:50%;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-.bg0 {
- background-color:#787878;
-}
-
-.bg1 {
- background-color:#FFFFFF;
-}
-
-.bold {
- font-weight:bold;
-}
-
-.boldItalic {
- font-weight:bolder;
- font-style:italic;
-}
-
-.italic {
- font-style:italic;
-}
-
-.inputTitle {
- margin-top:8px;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
- color:#006600;
- text-transform:uppercase;
-}
-
-.editpadImage {
- display:inline;
- width:670px;
- border-left:2px solid #E8E8E8;
- border-top:2px solid #E8E8E8;
- border-right:2px dashed #CC0033;
- border-bottom:2px dashed #CC0033;
-}
-
-#xbitCounter {
- margin-top:7px;
- padding-top:2px;
- padding-bottom:2px;
- border: 1px solid #787878;
- background-color:#E8E8E8;
-}
-
-a {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#006600;
-}
-
-.aiTable {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#006600;
-}
-
-.aiTable th {
- font-size:11pt;
- text-align:left;
-}
-
-.aiTable td {
- text-align:justify;
-}
-
-.lineDown {
- background-color:#006600;
-}
-
-.searchBox {
- background-color:#E8E8E8;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
- border-right: 2px #666666 solid;
- border-bottom: 2px #666666 solid;
- border-top: 1px #cccccc solid;
- border-left: 1px #cccccc solid;
-}
-
-.searchBox .searchTitle {
- font-family:'Whimsy TT',fantasy,cursive;
- font-size:20pt;
- font-variant:small-caps;
- color:#000000;
-}
-
-.buttonHi {
- background-color:#333333;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonHi {
- width:80px;
- background-color:#333333;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonLo {
- width:80px;
- background-color:#E8E8E8;
- color:#000000;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.folderView {
- display:block;
- background-image:url('../images/skin-03/folder-2.gif');
-}
+ /* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */ + +.dummy { + font-family:verdana, arial, helvetica, sans-serif; +} + + +/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */ + +body { + margin:0px; + padding:0px; + background-color:#FEFEFE; + font-size: 100% !important; + line-height: normal !important; +} + +.headerArea { + height:120px; + margin:0px; + padding:0px; + line-height:60%; + text-align:center; + color:#FFFFFF; + background-color:#333333; + background-image:url('../images/skin-03/theme-back.jpg'); +} + +.headerArea a { + color:#FFFFFF; +} + +.headerArea img { + margin-left:auto; + margin-right:auto; +} + +.h1 { + font-family: verdana,arial,helvetiva,sans-serif; + font-size:15pt; + font-weight:normal; + color:#000000; + border:3px #333333 double; + padding-top:4px; + padding-bottom:6px; + width:60%; + margin:0 auto; + background-color:#ECECEC; + text-align:center; +} + +.h2 { + margin-top:20px; + padding:0px; + font-family:Arial,Helvetica,sans-serif; + font-size:1.17em; + font-weight:normal; + color:#333333; +} + + +.h3 { + clear:both; + padding-top:16px; + padding-bottom:8px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 10pt; + color: #000066; +} + +.h3 span { + display:inline; + border-top: 1px #666666 solid; + border-bottom: 1px #666666 solid; + padding:0; + padding-top: 5px; + padding-bottom: 5px; + margin:0; +} + +.bestViewed { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:26px; + margin:0 auto; +} + +.pageMessage { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:16px; + margin:0 auto; + margin-bottom:30px; +} + +.footerArea { + clear:both; + width:100%; + text-align:center; + color:#000000; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.71em; + padding-top:0px; + background-color:#333333; + background-image:url('../images/skin-03/theme-back.jpg'); +} + +.footerText { + padding-top:4px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; +} + +.footerText a { + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; + text-decoration:underline; +} + +.footerText a:link {color: #FFFFFF; text-decoration: underline;} +.footerText a:visited {color: #FFFFFF; text-decoration: underline;} +.footerText a:hover {color: #FFFF00; text-decoration: underline;} +.footerText a:focus {color: #FF0000; text-decoration: underline;} +.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;} + + +/* ======= UNIVERSAL MAIN-MENU STYLES ======= */ + + +.mainMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#333333; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu li { + display:inline; +} + +.mainMenu a { + float:left; + width:90px; + color:#FFFFFF; + background-color:#333333; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #FFFFFF; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #FFFFFF; + text-align:center; + font-size:9pt; + font-weight:bold; + color:#000000; + background-color:#FFFFFF; + background-image:url('../images/skin-03/deadlink-back.gif'); +} + +.mainMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-03/hoverlink-back.gif'); +} + + +/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */ + + +.subMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#ECECEC; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu li { + display:inline; +} + +.subMenu a { + float:left; + width:90px; + color:#000000; + background-color:#E8E8E8; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #333333; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #333333; + text-align:center; + color:#000000; + background-color:#FFFFFF; + background-image:url('../images/skin-03/deadlink-back.gif'); + background-position: 0px -1px; +} + +.subMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-03/hoverlink-back.gif'); + background-position: 0px -1px; +} + + +/* ======= SITE TABLES/BOXES STYLES ======= */ + +.siteTable { + background-color:#333333; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; +} + +.siteTable .bg0 { + background-color:#333333; + color:#FFFFFF; +} + +.siteTable .bg1 { + background-color:#FEFEFE; + color:#006600; +} + +.siteTable .bg2 { + background-color:#E8E8E8; + color:#000000; +} + +.monoTable { + background-color:#333333; + font-family:monospace; + font-size:10pt; +} + +.monoTable .bg0 { + background-color:#333333; + color:#FFFFFF; +} + +.monoTable .bg1 { + background-color:#FEFEFE; + color:#006600; +} + +.monoTable .bg2 { + background-color:#E8E8E8; + color:#000000; +} + +.themesMenu { + display:block; + margin:0; +} + +.themesMenu table { + background-color:#838367; + font-family:Arial,Helvetica,sans-serif; + font-size:0.7em; + text-align:center; +} + +.themesMenu .bg1 { + background-color:#FFFFFF; + color:#006600; + font-weight:bold; +} + +.themesMenu .bg1 td { + padding-top:2px; + padding-bottom:2px; + text-align:center; +} + +.normText { + font-family:Times,'Times New Roman',Palatino,serif; + font-size:0.96em; + text-align:justify; +} + +.normText a { + font-family:Arial,Helvetica,sans-serif; + font-size:11pt; + text-align:justify; + text-decoration:underline; +} + +.normText a:link {color: #006600; text-decoration: underline;} +.normText a:visited {color: #009900; text-decoration: underline;} +.normText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + + +.demoText { + font-family:Times,'Times New Roman',Palatino,serif; + font-size:0.85em; + font-weight:normal; + color: #000000; + text-align:justify; +} + +.demoText a { + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + text-decoration:underline; +} + +.demoText a:link {color: #003300; text-decoration: underline;} +.demoText a:visited {color: #003300; text-decoration: underline;} +.demoText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + +.demoTextBold { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:bold; + color: #000000; + text-align:justify; +} + +.divHeader { + text-align:center; + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.72em; + padding:5px; + color:#FFFFFF; + border:0; + background-color:#333333; +} + +.divData { + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-weight:normal; + font-size:0.7em; + padding:5px; + color:#000000; + background-color:#E8E8E8; +} + +.divData a { + display:inline; + font-size:1em; + color:#000000; +} + +.codeBox { + font-family:monospace,courier; + font-size:9pt; + font-weight:normal; + color: #000000; + background-color:#ECECEC; + border:3px double #333333; + padding:7px; + margin-bottom:30px; +} + +.dataArea { + padding:0; + border:4px double #333333; + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; + line-height:140%; +} + +.dataArea .subArea1 { + padding:16px; + background-color:#E8E8E8; + color:#000033; +} + +.dataArea .subArea2 { + padding:16px; + background-color:#FEFEFE; + color:#000066; +} + +.dataArea .pseudoLink { + display:inline; + text-decoration:underline; + color:#000000; + font-size:10pt; + font-weight:normal; + cursor:pointer; +} + +.dataArea .pseudoLinkReverse { + display:inline; + color:#FFFFFF; + background-color:#333333; + font-size:9.4pt; + font-weight:bolder; + padding-left:4px; + padding-right:4px; +} + +.dataArea hr { + height:1px; + color:#48486E; +} + +fieldset { + display:block; + background-color:#FFFFFF; + border:2px dotted #333333; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + + +fieldset legend { + color: #000000; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-variant: small-caps; + font-size:11pt; + margin-top:10px; + padding: .3ex .8ex; + border:3px #333333 double; + font-weight: bold; + background-color:#ECECEC; +} + +.bankHolsInner { + display:block; + background-color:#ECECEC; + text-align:center; + margin:0 auto; + border:#333333 3px double; + padding:0.8em; +} + +.bankHolsTitle { + font-family:Verdana,Arial,Helvetica,sans-serif; + font-size:11pt; + font-weight:bolder; + color:#000000; + margin-bottom:7px; +} + +.hexRgbOuter { + float:left; + margin-top:7px; + margin-right:20px; +} + +.hexRgbInner { + display:block; + background-color:#ECECEC; + text-align:center; + margin:0 auto; + border:#333333 3px double; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +.multiSearchOuter { + text-align:center; +} + +.multiSearchInner { + width:440px; + padding-left:10px; + padding-right:10px; + padding-bottom:10px; + margin-left:auto; + margin-right:auto; + background-color:#ECECEC; + border:#333333 3px double; +} + +.multiSearchOuter table { + width:400px; + text-align:left; + margin-left:auto; + margin-right:auto; +} + +.lineAcross1 { + clear:both; + display:block; + background:url('../images/skin-03/line-horz-1.gif'); +} + +.lineAcross2 { + clear:both; + display:block; + background:url('../images/skin-03/line-horz-2.gif'); +} + +.lineAcross3 { + clear:both; + display:block; + background:url('../images/skin-03/line-horz-3.gif'); +} + +.lineAcross4 { + clear:both; + display:block; + background:url('../images/skin-03/line-horz-4.gif'); +} + +.siteMap a { + border: 2px solid #FEFEFE; +} + +#fixedBack { + background-image:url('../images/skin-03/fixed-back.gif'); + background-attachment:fixed; +} + +.redNote { + font-family:tahoma,arial,sans-serif; + font-size:10pt; + font-weight:bold; + font-style:italic; + color: #333333; + margin-left:15px; +} + +.fancyLink { + width:360px; + text-align:justify; + line-height:0.96em; +} + +.fancyLink a { + font-family:arial,helvetica,sans-serif; + font-weight:normal; + font-size:9pt; + color:#666666; + text-decoration:none; +} + +.fancyLink em { + font-size:9pt; + font-family:tahoma,arial,helvetica,sans-serif; + font-weight:bold; + font-style:normal; + text-transform:none; + color:#333333; + text-decoration:underline; +} + +.fancyLink small { + font-family:arial,helvetica,sans-serif; + font-size:8pt; + font-weight:normal; + font-style:normal; + color:#333333; + text-decoration:underline; +} + +.fancyLink .lineDown { + background-color:#333333; +} + +.red { + color:#FF0000; +} + +.htmCode { + color:#C00000; + font-family:courier,monospace; +} + +.cssCode { + color:#0033FF; + font-family:courier,monospace; +} + +.green { + color:#009933; + font-family:courier,monospace; +} + +.linksFieldset { + width:50%; + text-align:center; + margin-left:auto; + margin-right:auto; +} + +.bg0 { + background-color:#787878; +} + +.bg1 { + background-color:#FFFFFF; +} + +.bold { + font-weight:bold; +} + +.boldItalic { + font-weight:bolder; + font-style:italic; +} + +.italic { + font-style:italic; +} + +.inputTitle { + margin-top:8px; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; + color:#006600; + text-transform:uppercase; +} + +.editpadImage { + display:inline; + width:670px; + border-left:2px solid #E8E8E8; + border-top:2px solid #E8E8E8; + border-right:2px dashed #CC0033; + border-bottom:2px dashed #CC0033; +} + +#xbitCounter { + margin-top:7px; + padding-top:2px; + padding-bottom:2px; + border: 1px solid #787878; + background-color:#E8E8E8; +} + +a { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#006600; +} + +.aiTable { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#006600; +} + +.aiTable th { + font-size:11pt; + text-align:left; +} + +.aiTable td { + text-align:justify; +} + +.lineDown { + background-color:#006600; +} + +.searchBox { + background-color:#E8E8E8; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; + border-right: 2px #666666 solid; + border-bottom: 2px #666666 solid; + border-top: 1px #cccccc solid; + border-left: 1px #cccccc solid; +} + +.searchBox .searchTitle { + font-family:'Whimsy TT',fantasy,cursive; + font-size:20pt; + font-variant:small-caps; + color:#000000; +} + +.buttonHi { + background-color:#333333; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonHi { + width:80px; + background-color:#333333; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonLo { + width:80px; + background-color:#E8E8E8; + color:#000000; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.folderView { + display:block; + background-image:url('../images/skin-03/folder-2.gif'); +} diff --git a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-4.css b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-4.css index a330b833..d247b392 100644 --- a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-4.css +++ b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-4.css @@ -1,753 +1,753 @@ -/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */
-
-.dummy {
- font-family:verdana, arial, helvetica, sans-serif;
-}
-
-
-/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */
-
-body {
- margin:0px;
- padding:0px;
- background-color:#EBFFED;
- font-size: 100% !important;
- line-height: normal !important;
-}
-
-.headerArea {
- height:120px;
- margin:0px;
- padding:0px;
- line-height:60%;
- text-align:center;
- color:#FFFFFF;
- background-color:#066E06;
- background-image:url('../images/skin-04/theme-back.jpg');
-}
-
-.headerArea a {
- color:#FFFFFF;
-}
-
-.headerArea img {
- margin-left:auto;
- margin-right:auto;
-}
-
-.h1 {
- font-family:Verdana,Arial,Geneva,Helvetica,sans-serif;
- font-size:15pt;
- font-weight:normal;
- color:#003300;
- border:3px double #066E06;
- padding-top:4px;
- padding-bottom:6px;
- width:60%;
- margin:0 auto;
- background-color:#C3F4C3;
- text-align:center;
-}
-
-.h2 {
- margin-top:20px;
- padding:0px;
- font-family:VerdanaArial,Geneva,Helvetica,sans-serif;
- font-size:1.17em;
- font-weight:normal;
- color:#006600;
-}
-
-
-.h3 {
- clear:both;
- padding-top:16px;
- padding-bottom:8px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 10pt;
- color: #006600;
-}
-
-.h3 span {
- display:inline;
- border-top: 1px #666666 solid;
- border-bottom: 1px #666666 solid;
- padding:0;
- padding-top: 5px;
- padding-bottom: 5px;
- margin:0;
-}
-
-.bestViewed {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:26px;
- margin:0 auto;
-}
-
-.pageMessage {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:16px;
- margin:0 auto;
- margin-bottom:30px;
-}
-
-.footerArea {
- clear:both;
- width:100%;
- text-align:center;
- color:#FFFFFF;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.71em;
- padding-top:0px;
- background-color:#066E06;
- background-image:url('../images/skin-04/theme-back.jpg');
-}
-
-.footerText {
- padding-top:4px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
-}
-
-.footerText a {
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
- text-decoration:underline;
-}
-
-.footerText a:link {color: #FFFFFF; text-decoration: underline;}
-.footerText a:visited {color: #FFFFFF; text-decoration: underline;}
-.footerText a:hover {color: #FFFF00; text-decoration: underline;}
-.footerText a:focus {color: #FF0000; text-decoration: underline;}
-.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;}
-
-
-/* ======= UNIVERSAL MAIN-MENU STYLES ======= */
-
-
-.mainMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#066E06;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu li {
- display:inline;
-}
-
-.mainMenu a {
- float:left;
- width:90px;
- color:#FFFFFF;
- background-color:#066E06;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #CCFFCC;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #CCFFCC;
- text-align:center;
- font-size:9pt;
- font-weight:bold;
- color:#006600;
- background-color:#FFFFFF;
- background-image:url('../images/skin-04/deadlink-back.gif');
-}
-
-.mainMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-04/hoverlink-back.gif');
-}
-
-
-/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */
-
-
-.subMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#C3F4C3;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu li {
- display:inline;
-}
-
-.subMenu a {
- float:left;
- width:90px;
- color:#006600;
- background-color:#C3F4C3;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #066E06;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #066E06;
- text-align:center;
- color:#006600;
- background-color:#FFFFFF;
- background-image:url('../images/skin-04/deadlink-back.gif');
- background-position: 0px -1px;
-}
-
-.subMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-04/hoverlink-back.gif');
- background-position: 0px -1px;
-}
-
-
-/* ======= SITE TABLES/BOXES STYLES ======= */
-
-.siteTable {
- background-color:#066E06;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
-}
-
-.siteTable .bg0 {
- background-color:#066E06;
- color:#FFFFFF;
-}
-
-.siteTable .bg1 {
- background-color:#EBFFED;
- color:#003300;
-}
-
-.siteTable .bg2 {
- background-color:#C3F4C3;
- color:#006600;
-}
-
-.monoTable {
- background-color:#066E06;
- font-family:monospace;
- font-size:10pt;
-}
-
-.monoTable .bg0 {
- background-color:#066E06;
- color:#FFFFFF;
-}
-
-.monoTable .bg1 {
- background-color:#EBFFED;
- color:#003300;
-}
-
-.monoTable .bg2 {
- background-color:#C3F4C3;
- color:#006600;
-}
-
-.themesMenu {
- display:block;
- margin:0;
-}
-
-.themesMenu table {
- background-color:#066E06;
- font-family:Arial,Helvetica,sans-serif;
- font-size:0.7em;
- text-align:center;
-}
-
-.themesMenu .bg1 {
- background-color:#FFFFFF;
- color:#006600;
- font-weight:bold;
-}
-
-.themesMenu .bg1 td {
- padding-top:2px;
- padding-bottom:2px;
- text-align:center;
-}
-
-.divHeader {
- text-align:center;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.72em;
- padding:5px;
- color:#FFFFFF;
- border:0;
- background-color:#066E06;
-}
-
-.divData {
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:normal;
- font-size:0.7em;
- padding:5px;
- color:#006600;
- background-color:#C3F4C3;
-}
-
-.divData a {
- display:inline;
- font-size:1em;
- color:#006600;
-}
-
-.codeBox {
- font-family:monospace,courier;
- font-size:9pt;
- font-weight:normal;
- color: #003300;
- background-color:#C3F4C3;
- border:3px double #066E06;
- padding:7px;
- margin-bottom:30px;
-}
-
-.dataArea {
- padding:0;
- border:4px double #066E06;
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
- line-height:140%;
-}
-
-.dataArea .subArea1 {
- padding:16px;
- background-color:#C3F4C3;
- color:#000033;
-}
-
-.dataArea .subArea2 {
- padding:16px;
- background-color:#EBFFED;
- color:#000066;
-}
-
-.dataArea .pseudoLink {
- display:inline;
- text-decoration:underline;
- color:#000000;
- font-size:10pt;
- font-weight:normal;
- cursor:pointer;
-}
-
-.dataArea .pseudoLinkReverse {
- display:inline;
- color:#FFFFFF;
- background-color:#066E06;
- font-size:9.4pt;
- font-weight:bolder;
- padding-left:4px;
- padding-right:4px;
-}
-
-.dataArea hr {
- height:1px;
- color:#48486E;
-}
-
-fieldset {
- display:block;
- background-color:#EBFFED;
- border:2px dotted #066E06;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-fieldset legend {
- color: #066E06;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-variant: small-caps;
- font-size:11pt;
- margin-top:10px;
- padding: .3ex .8ex;
- border:3px #066E06 double;
- font-weight: bold;
- background-color:#C3F4C3;
-}
-
-.bankHolsInner {
- display:block;
- background-color:#C3F4C3;
- text-align:center;
- margin:0 auto;
- border:#066E06 3px double;
- padding:0.8em;
-}
-
-.bankHolsTitle {
- font-family:Verdana,Arial,Helvetica,sans-serif;
- font-size:11pt;
- font-weight:bolder;
- color:#003300;
- margin-bottom:7px;
-}
-
-.hexRgbOuter {
- float:left;
- margin-top:7px;
- margin-right:20px;
-}
-
-.hexRgbInner {
- display:block;
- background-color:#C3F4C3;
- text-align:center;
- margin:0 auto;
- border:#066E06 3px double;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-.multiSearchOuter {
- text-align:center;
-}
-
-.multiSearchInner {
- width:440px;
- padding-left:10px;
- padding-right:10px;
- padding-bottom:10px;
- margin-left:auto;
- margin-right:auto;
- background-color:#C3F4C3;
- border:#066E06 3px double;
-}
-
-.multiSearchOuter table {
- width:400px;
- text-align:left;
- margin-left:auto;
- margin-right:auto;
-}
-
-.lineAcross1 {
- clear:both;
- display:block;
- background:url('../images/skin-04/line-horz-1.gif');
-}
-
-.lineAcross2 {
- clear:both;
- display:block;
- background:url('../images/skin-04/line-horz-2.gif');
-}
-
-.lineAcross3 {
- clear:both;
- display:block;
- background:url('../images/skin-04/line-horz-3.gif');
-}
-
-.lineAcross4 {
- clear:both;
- display:block;
- background:url('../images/skin-04/line-horz-4.gif');
-}
-
-.normText {
- font-family:Arial,Verdana,Geneva,Helvetica,sans-serif;
- font-size:0.96em;
- font-weight:normal;
- text-align:left;
- color:#000000;
-}
-
-.normText a {
- font-family:Arial,Helvetica,sans-serif;
- font-size:11pt;
- text-align:justify;
- text-decoration:underline;
-}
-
-.normText a:link {color: #006600; text-decoration: underline;}
-.normText a:visited {color: #009900; text-decoration: underline;}
-.normText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-
-.demoText {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
- text-align:justify;
-}
-
-.demoText a {
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- text-decoration:underline;
-}
-
-.demoText a:link {color: #003300; text-decoration: underline;}
-.demoText a:visited {color: #003300; text-decoration: underline;}
-.demoText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-.demoTextBold {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:bold;
- color: #000000;
- text-align:justify;
-}
-
-.siteMap a {
- border: 2px solid #EBFFED;
-}
-
-#fixedBack {
- background-image:url('../images/skin-04/fixed-back.gif');
- background-attachment:fixed;
-}
-
-.redNote {
- font-family:tahoma,arial,sans-serif;
- font-size:10pt;
- font-weight:bold;
- font-style:italic;
- color: #CC3300;
- margin-left:15px;
-}
-
-.fancyLink {
- width:360px;
- text-align:justify;
- line-height:0.96em;
-}
-
-.fancyLink a {
- font-family:arial,helvetica,sans-serif;
- font-weight:normal;
- font-size:9pt;
- color:#990000;
- text-decoration:none;
-}
-
-.fancyLink em {
- font-size:9pt;
- font-family:tahoma,arial,helvetica,sans-serif;
- font-weight:bold;
- font-style:normal;
- text-transform:none;
- color:#006600;
- text-decoration:underline;
-}
-
-.fancyLink small {
- font-family:arial,helvetica,sans-serif;
- font-size:8pt;
- font-weight:normal;
- font-style:normal;
- color:#006600;
- text-decoration:underline;
-}
-
-.fancyLink .lineDown {
- background-color:#858654;
-}
-
-.red {
- color:#FF0000;
-}
-
-.htmCode {
- color:#C00000;
- font-family:courier,monospace;
-}
-
-.cssCode {
- color:#0033FF;
- font-family:courier,monospace;
-}
-
-.green {
- color:#009933;
- font-family:courier,monospace;
-}
-
-.linksFieldset {
- width:50%;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-.bg0 {
- background-color:#858654;
-}
-
-.bg1 {
- background-color:#FFFFFF;
-}
-
-.bold {
- font-weight:bold;
-}
-
-.boldItalic {
- font-weight:bolder;
- font-style:italic;
-}
-
-.italic {
- font-style:italic;
-}
-
-.inputTitle {
- margin-top:8px;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
- color:#006600;
- text-transform:uppercase;
-}
-
-.editpadImage {
- display:inline;
- width:670px;
- border-left:2px solid #D2D2A5;
- border-top:2px solid #D2D2A5;
- border-right:2px dashed #CC0033;
- border-bottom:2px dashed #CC0033;
-}
-
-#xbitCounter {
- margin-top:7px;
- padding-top:2px;
- padding-bottom:2px;
- border: 1px solid #858654;
- background-color:#D2D2A5;
-}
-
-a {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#006600;
-}
-
-.aiTable {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#006600;
-}
-
-.aiTable th {
- font-size:11pt;
- text-align:left;
-}
-
-.aiTable td {
- text-align:justify;
-}
-
-.lineDown {
- background-color:#006600;
-}
-
-.searchBox {
- background-color:#C3F4C3;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #006600;
- border-right: 2px #666666 solid;
- border-bottom: 2px #666666 solid;
- border-top: 1px #cccccc solid;
- border-left: 1px #cccccc solid;
-}
-
-.searchBox .searchTitle {
- font-family:'Whimsy TT',fantasy,cursive;
- font-size:20pt;
- font-variant:small-caps;
- color:#006600;
-}
-
-.buttonHi {
- background-color:#066E06;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonHi {
- width:80px;
- background-color:#066E06;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonLo {
- width:80px;
- background-color:#C3F4C3;
- color:#006600;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.folderView {
- display:block;
- background-image:url('../images/skin-04/folder-2.gif');
-}
+/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */ + +.dummy { + font-family:verdana, arial, helvetica, sans-serif; +} + + +/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */ + +body { + margin:0px; + padding:0px; + background-color:#EBFFED; + font-size: 100% !important; + line-height: normal !important; +} + +.headerArea { + height:120px; + margin:0px; + padding:0px; + line-height:60%; + text-align:center; + color:#FFFFFF; + background-color:#066E06; + background-image:url('../images/skin-04/theme-back.jpg'); +} + +.headerArea a { + color:#FFFFFF; +} + +.headerArea img { + margin-left:auto; + margin-right:auto; +} + +.h1 { + font-family:Verdana,Arial,Geneva,Helvetica,sans-serif; + font-size:15pt; + font-weight:normal; + color:#003300; + border:3px double #066E06; + padding-top:4px; + padding-bottom:6px; + width:60%; + margin:0 auto; + background-color:#C3F4C3; + text-align:center; +} + +.h2 { + margin-top:20px; + padding:0px; + font-family:VerdanaArial,Geneva,Helvetica,sans-serif; + font-size:1.17em; + font-weight:normal; + color:#006600; +} + + +.h3 { + clear:both; + padding-top:16px; + padding-bottom:8px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 10pt; + color: #006600; +} + +.h3 span { + display:inline; + border-top: 1px #666666 solid; + border-bottom: 1px #666666 solid; + padding:0; + padding-top: 5px; + padding-bottom: 5px; + margin:0; +} + +.bestViewed { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:26px; + margin:0 auto; +} + +.pageMessage { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:16px; + margin:0 auto; + margin-bottom:30px; +} + +.footerArea { + clear:both; + width:100%; + text-align:center; + color:#FFFFFF; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.71em; + padding-top:0px; + background-color:#066E06; + background-image:url('../images/skin-04/theme-back.jpg'); +} + +.footerText { + padding-top:4px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; +} + +.footerText a { + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; + text-decoration:underline; +} + +.footerText a:link {color: #FFFFFF; text-decoration: underline;} +.footerText a:visited {color: #FFFFFF; text-decoration: underline;} +.footerText a:hover {color: #FFFF00; text-decoration: underline;} +.footerText a:focus {color: #FF0000; text-decoration: underline;} +.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;} + + +/* ======= UNIVERSAL MAIN-MENU STYLES ======= */ + + +.mainMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#066E06; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu li { + display:inline; +} + +.mainMenu a { + float:left; + width:90px; + color:#FFFFFF; + background-color:#066E06; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #CCFFCC; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #CCFFCC; + text-align:center; + font-size:9pt; + font-weight:bold; + color:#006600; + background-color:#FFFFFF; + background-image:url('../images/skin-04/deadlink-back.gif'); +} + +.mainMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-04/hoverlink-back.gif'); +} + + +/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */ + + +.subMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#C3F4C3; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu li { + display:inline; +} + +.subMenu a { + float:left; + width:90px; + color:#006600; + background-color:#C3F4C3; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #066E06; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #066E06; + text-align:center; + color:#006600; + background-color:#FFFFFF; + background-image:url('../images/skin-04/deadlink-back.gif'); + background-position: 0px -1px; +} + +.subMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-04/hoverlink-back.gif'); + background-position: 0px -1px; +} + + +/* ======= SITE TABLES/BOXES STYLES ======= */ + +.siteTable { + background-color:#066E06; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; +} + +.siteTable .bg0 { + background-color:#066E06; + color:#FFFFFF; +} + +.siteTable .bg1 { + background-color:#EBFFED; + color:#003300; +} + +.siteTable .bg2 { + background-color:#C3F4C3; + color:#006600; +} + +.monoTable { + background-color:#066E06; + font-family:monospace; + font-size:10pt; +} + +.monoTable .bg0 { + background-color:#066E06; + color:#FFFFFF; +} + +.monoTable .bg1 { + background-color:#EBFFED; + color:#003300; +} + +.monoTable .bg2 { + background-color:#C3F4C3; + color:#006600; +} + +.themesMenu { + display:block; + margin:0; +} + +.themesMenu table { + background-color:#066E06; + font-family:Arial,Helvetica,sans-serif; + font-size:0.7em; + text-align:center; +} + +.themesMenu .bg1 { + background-color:#FFFFFF; + color:#006600; + font-weight:bold; +} + +.themesMenu .bg1 td { + padding-top:2px; + padding-bottom:2px; + text-align:center; +} + +.divHeader { + text-align:center; + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.72em; + padding:5px; + color:#FFFFFF; + border:0; + background-color:#066E06; +} + +.divData { + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-weight:normal; + font-size:0.7em; + padding:5px; + color:#006600; + background-color:#C3F4C3; +} + +.divData a { + display:inline; + font-size:1em; + color:#006600; +} + +.codeBox { + font-family:monospace,courier; + font-size:9pt; + font-weight:normal; + color: #003300; + background-color:#C3F4C3; + border:3px double #066E06; + padding:7px; + margin-bottom:30px; +} + +.dataArea { + padding:0; + border:4px double #066E06; + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; + line-height:140%; +} + +.dataArea .subArea1 { + padding:16px; + background-color:#C3F4C3; + color:#000033; +} + +.dataArea .subArea2 { + padding:16px; + background-color:#EBFFED; + color:#000066; +} + +.dataArea .pseudoLink { + display:inline; + text-decoration:underline; + color:#000000; + font-size:10pt; + font-weight:normal; + cursor:pointer; +} + +.dataArea .pseudoLinkReverse { + display:inline; + color:#FFFFFF; + background-color:#066E06; + font-size:9.4pt; + font-weight:bolder; + padding-left:4px; + padding-right:4px; +} + +.dataArea hr { + height:1px; + color:#48486E; +} + +fieldset { + display:block; + background-color:#EBFFED; + border:2px dotted #066E06; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +fieldset legend { + color: #066E06; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-variant: small-caps; + font-size:11pt; + margin-top:10px; + padding: .3ex .8ex; + border:3px #066E06 double; + font-weight: bold; + background-color:#C3F4C3; +} + +.bankHolsInner { + display:block; + background-color:#C3F4C3; + text-align:center; + margin:0 auto; + border:#066E06 3px double; + padding:0.8em; +} + +.bankHolsTitle { + font-family:Verdana,Arial,Helvetica,sans-serif; + font-size:11pt; + font-weight:bolder; + color:#003300; + margin-bottom:7px; +} + +.hexRgbOuter { + float:left; + margin-top:7px; + margin-right:20px; +} + +.hexRgbInner { + display:block; + background-color:#C3F4C3; + text-align:center; + margin:0 auto; + border:#066E06 3px double; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +.multiSearchOuter { + text-align:center; +} + +.multiSearchInner { + width:440px; + padding-left:10px; + padding-right:10px; + padding-bottom:10px; + margin-left:auto; + margin-right:auto; + background-color:#C3F4C3; + border:#066E06 3px double; +} + +.multiSearchOuter table { + width:400px; + text-align:left; + margin-left:auto; + margin-right:auto; +} + +.lineAcross1 { + clear:both; + display:block; + background:url('../images/skin-04/line-horz-1.gif'); +} + +.lineAcross2 { + clear:both; + display:block; + background:url('../images/skin-04/line-horz-2.gif'); +} + +.lineAcross3 { + clear:both; + display:block; + background:url('../images/skin-04/line-horz-3.gif'); +} + +.lineAcross4 { + clear:both; + display:block; + background:url('../images/skin-04/line-horz-4.gif'); +} + +.normText { + font-family:Arial,Verdana,Geneva,Helvetica,sans-serif; + font-size:0.96em; + font-weight:normal; + text-align:left; + color:#000000; +} + +.normText a { + font-family:Arial,Helvetica,sans-serif; + font-size:11pt; + text-align:justify; + text-decoration:underline; +} + +.normText a:link {color: #006600; text-decoration: underline;} +.normText a:visited {color: #009900; text-decoration: underline;} +.normText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + + +.demoText { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; + text-align:justify; +} + +.demoText a { + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + text-decoration:underline; +} + +.demoText a:link {color: #003300; text-decoration: underline;} +.demoText a:visited {color: #003300; text-decoration: underline;} +.demoText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + +.demoTextBold { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:bold; + color: #000000; + text-align:justify; +} + +.siteMap a { + border: 2px solid #EBFFED; +} + +#fixedBack { + background-image:url('../images/skin-04/fixed-back.gif'); + background-attachment:fixed; +} + +.redNote { + font-family:tahoma,arial,sans-serif; + font-size:10pt; + font-weight:bold; + font-style:italic; + color: #CC3300; + margin-left:15px; +} + +.fancyLink { + width:360px; + text-align:justify; + line-height:0.96em; +} + +.fancyLink a { + font-family:arial,helvetica,sans-serif; + font-weight:normal; + font-size:9pt; + color:#990000; + text-decoration:none; +} + +.fancyLink em { + font-size:9pt; + font-family:tahoma,arial,helvetica,sans-serif; + font-weight:bold; + font-style:normal; + text-transform:none; + color:#006600; + text-decoration:underline; +} + +.fancyLink small { + font-family:arial,helvetica,sans-serif; + font-size:8pt; + font-weight:normal; + font-style:normal; + color:#006600; + text-decoration:underline; +} + +.fancyLink .lineDown { + background-color:#858654; +} + +.red { + color:#FF0000; +} + +.htmCode { + color:#C00000; + font-family:courier,monospace; +} + +.cssCode { + color:#0033FF; + font-family:courier,monospace; +} + +.green { + color:#009933; + font-family:courier,monospace; +} + +.linksFieldset { + width:50%; + text-align:center; + margin-left:auto; + margin-right:auto; +} + +.bg0 { + background-color:#858654; +} + +.bg1 { + background-color:#FFFFFF; +} + +.bold { + font-weight:bold; +} + +.boldItalic { + font-weight:bolder; + font-style:italic; +} + +.italic { + font-style:italic; +} + +.inputTitle { + margin-top:8px; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; + color:#006600; + text-transform:uppercase; +} + +.editpadImage { + display:inline; + width:670px; + border-left:2px solid #D2D2A5; + border-top:2px solid #D2D2A5; + border-right:2px dashed #CC0033; + border-bottom:2px dashed #CC0033; +} + +#xbitCounter { + margin-top:7px; + padding-top:2px; + padding-bottom:2px; + border: 1px solid #858654; + background-color:#D2D2A5; +} + +a { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#006600; +} + +.aiTable { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#006600; +} + +.aiTable th { + font-size:11pt; + text-align:left; +} + +.aiTable td { + text-align:justify; +} + +.lineDown { + background-color:#006600; +} + +.searchBox { + background-color:#C3F4C3; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #006600; + border-right: 2px #666666 solid; + border-bottom: 2px #666666 solid; + border-top: 1px #cccccc solid; + border-left: 1px #cccccc solid; +} + +.searchBox .searchTitle { + font-family:'Whimsy TT',fantasy,cursive; + font-size:20pt; + font-variant:small-caps; + color:#006600; +} + +.buttonHi { + background-color:#066E06; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonHi { + width:80px; + background-color:#066E06; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonLo { + width:80px; + background-color:#C3F4C3; + color:#006600; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.folderView { + display:block; + background-image:url('../images/skin-04/folder-2.gif'); +} diff --git a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-5.css b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-5.css index 24e0e03e..01280605 100644 --- a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-5.css +++ b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-5.css @@ -1,752 +1,752 @@ -/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */
-
-.dummy {
- font-family:verdana, arial, helvetica, sans-serif;
-}
-
-
-/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */
-
-body {
- margin:0px;
- padding:0px;
- background-color:#ECFFFF;
- font-size: 100% !important;
- line-height: normal !important;
-}
-
-.headerArea {
- height:120px;
- margin:0px;
- padding:0px;
- line-height:60%;
- text-align:center;
- color:#FFFFFF;
- background-color:#3F6876;
- background-image:url('../images/skin-05/theme-back.jpg');
-}
-
-.headerArea a {
- color:#FFFFFF;
-}
-
-.headerArea img {
- margin-left:auto;
- margin-right:auto;
-}
-
-.h1 {
- font-family: verdana,arial,helvetiva,sans-serif;
- font-size:15pt;
- font-weight:normal;
- color:#3F6876;
- border:3px #3F6876 double;
- padding-top:4px;
- padding-bottom:6px;
- width:60%;
- margin:0 auto;
- background-color:#AEFBFB;
- text-align:center;
-}
-
-.h2 {
- margin-top:20px;
- padding:0px;
- font-family:Arial,Helvetica,sans-serif;
- font-size:1.17em;
- font-weight:normal;
- color:#333333;
-}
-
-
-.h3 {
- clear:both;
- padding-top:16px;
- padding-bottom:8px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 10pt;
- color: #000066;
-}
-
-.h3 span {
- display:inline;
- border-top: 1px #666666 solid;
- border-bottom: 1px #666666 solid;
- padding:0;
- padding-top: 5px;
- padding-bottom: 5px;
- margin:0;
-}
-
-.bestViewed {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:26px;
- margin:0 auto;
-}
-
-.pageMessage {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:16px;
- margin:0 auto;
- margin-bottom:30px;
-}
-
-.footerArea {
- clear:both;
- width:100%;
- text-align:center;
- color:#FFFFFF;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.71em;
- padding-top:0px;
- background-color:#3F6876;
- background-image:url('../images/skin-05/theme-back.jpg');
-}
-
-.footerText {
- padding-top:4px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
-}
-
-.footerText a {
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
- text-decoration:underline;
-}
-
-.footerText a:link {color: #FFFFFF; text-decoration: underline;}
-.footerText a:visited {color: #FFFFFF; text-decoration: underline;}
-.footerText a:hover {color: #FFFF00; text-decoration: underline;}
-.footerText a:focus {color: #FF0000; text-decoration: underline;}
-.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;}
-
-
-/* ======= UNIVERSAL MAIN-MENU STYLES ======= */
-
-
-.mainMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#3F6876;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu li {
- display:inline;
-}
-
-.mainMenu a {
- float:left;
- width:90px;
- color:#FFFFFF;
- background-color:#3F6876;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #FFFFFF;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #FFFFFF;
- text-align:center;
- font-size:9pt;
- font-weight:bold;
- color:#000000;
- background-color:#FFFFFF;
- background-image:url('../images/skin-05/deadlink-back.gif');
-}
-
-.mainMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-05/hoverlink-back.gif');
-}
-
-
-/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */
-
-
-.subMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#AEFBFB;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu li {
- display:inline;
-}
-
-.subMenu a {
- float:left;
- width:90px;
- color:#000000;
- background-color:#AEFBFB;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #787878;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #787878;
- text-align:center;
- color:#000000;
- background-color:#FFFFFF;
- background-image:url('../images/skin-05/deadlink-back.gif');
- background-position: 0px -1px;
-}
-
-.subMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-05/hoverlink-back.gif');
- background-position: 0px -1px;
-}
-
-
-/* ======= SITE TABLES/BOXES STYLES ======= */
-
-.siteTable {
- background-color:#3F6876;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
-}
-
-.siteTable .bg0 {
- background-color:#3F6876;
- color:#FFFFFF;
-}
-
-.siteTable .bg1 {
- background-color:#ECFFFF;
- color:#006600;
-}
-
-.siteTable .bg2 {
- background-color:#AEFBFB;
- color:#006600;
-}
-
-.monoTable {
- background-color:#3F6876;
- font-family:monospace;
- font-size:10pt;
-}
-
-.monoTable .bg0 {
- background-color:#3F6876;
- color:#FFFFFF;
-}
-
-.monoTable .bg1 {
- background-color:#ECFFFF;
- color:#006600;
-}
-
-.monoTable .bg2 {
- background-color:#AEFBFB;
- color:#006600;
-}
-
-.themesMenu {
- display:block;
- margin:0;
-}
-
-.themesMenu table {
- background-color:#3F6876;
- font-family:Arial,Helvetica,sans-serif;
- font-size:0.7em;
- text-align:center;
-}
-
-.themesMenu .bg1 {
- background-color:#FFFFFF;
- color:#006600;
- font-weight:bold;
-}
-
-.themesMenu .bg1 td {
- padding-top:2px;
- padding-bottom:2px;
- text-align:center;
-}
-
-.normText {
- font-family:Arial,Helvetica,sans-serif;
- font-size:0.96em;
- text-align:left;
-}
-
-.normText a {
- font-family:Arial,Helvetica,sans-serif;
- font-size:11pt;
- text-align:justify;
- text-decoration:underline;
-}
-
-.normText a:link {color: #006600; text-decoration: underline;}
-.normText a:visited {color: #009900; text-decoration: underline;}
-.normText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-
-.demoText {
- font-family:Times,'Times New Roman',Palatino,serif;
- font-size:0.85em;
- font-weight:normal;
- color: #000000;
- text-align:justify;
-}
-
-.demoText a {
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- text-decoration:underline;
-}
-
-.demoText a:link {color: #003300; text-decoration: underline;}
-.demoText a:visited {color: #003300; text-decoration: underline;}
-.demoText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-.demoTextBold {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:bold;
- color: #000000;
- text-align:justify;
-}
-
-.divHeader {
- text-align:center;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.72em;
- padding:5px;
- color:#FFFFFF;
- border:0;
- background-color:#3F6876;
-}
-
-.divData {
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:normal;
- font-size:0.7em;
- padding:5px;
- color:#000000;
- background-color:#AEFBFB;
-}
-
-.divData a {
- display:inline;
- font-size:1em;
- color:#000000;
-}
-
-.codeBox {
- font-family:monospace,courier;
- font-size:9pt;
- font-weight:normal;
- color: #000000;
- background-color:#AEFBFB;
- border:3px double #3F6876;
- padding:7px;
- margin-bottom:30px;
-}
-
-.dataArea {
- padding:0;
- border:4px double #3F6876;
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
- line-height:140%;
-}
-
-.dataArea .subArea1 {
- padding:16px;
- background-color:#AEFBFB;
- color:#000033;
-}
-
-.dataArea .subArea2 {
- padding:16px;
- background-color:#ECFFFF;
- color:#000066;
-}
-
-.dataArea .pseudoLink {
- display:inline;
- text-decoration:underline;
- color:#000000;
- font-size:10pt;
- font-weight:normal;
- cursor:pointer;
-}
-
-.dataArea .pseudoLinkReverse {
- display:inline;
- color:#FFFFFF;
- background-color:#3F6876;
- font-size:9.4pt;
- font-weight:bolder;
- padding-left:4px;
- padding-right:4px;
-}
-
-.dataArea hr {
- height:1px;
- color:#48486E;
-}
-
-fieldset {
- display:block;
- background-color:#ECFFFF;
- border:2px dotted #3F6876;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-
-fieldset legend {
- color: #000000;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-variant: small-caps;
- font-size:11pt;
- margin-top:10px;
- padding: .3ex .8ex;
- border:3px #3F6876 double;
- font-weight: bold;
- background-color:#AEFBFB;
-}
-
-.bankHolsInner {
- display:block;
- background-color:#AEFBFB;
- text-align:center;
- margin:0 auto;
- border:#3F6876 3px double;
- padding:0.8em;
-}
-
-.bankHolsTitle {
- font-family:Verdana,Arial,Helvetica,sans-serif;
- font-size:11pt;
- font-weight:bolder;
- color:#3F6876;
- margin-bottom:7px;
-}
-
-.hexRgbOuter {
- float:left;
- margin-top:7px;
- margin-right:20px;
-}
-
-.hexRgbInner {
- display:block;
- background-color:#AEFBFB;
- text-align:center;
- margin:0 auto;
- border:#3F6876 3px double;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-.multiSearchOuter {
- text-align:center;
-}
-
-.multiSearchInner {
- width:440px;
- padding-left:10px;
- padding-right:10px;
- padding-bottom:10px;
- margin-left:auto;
- margin-right:auto;
- background-color:#AEFBFB;
- border:#3F6876 3px double;
-}
-
-.multiSearchOuter table {
- width:400px;
- text-align:left;
- margin-left:auto;
- margin-right:auto;
-}
-
-.lineAcross1 {
- clear:both;
- display:block;
- background:url('../images/skin-05/line-horz-1.gif');
-}
-
-.lineAcross2 {
- clear:both;
- display:block;
- background:url('../images/skin-05/line-horz-2.gif');
-}
-
-.lineAcross3 {
- clear:both;
- display:block;
- background:url('../images/skin-05/line-horz-3.gif');
-}
-
-.lineAcross4 {
- clear:both;
- display:block;
- background:url('../images/skin-05/line-horz-4.gif');
-}
-
-.siteMap a {
- border: 2px solid #ECFFFF;
-}
-
-#fixedBack {
- background-image:url('../images/skin-05/fixed-back.gif');
- background-attachment:fixed;
-}
-
-.redNote {
- font-family:tahoma,arial,sans-serif;
- font-size:10pt;
- font-weight:bold;
- font-style:italic;
- color: #333333;
- margin-left:15px;
-}
-
-.fancyLink {
- width:360px;
- text-align:justify;
- line-height:0.96em;
-}
-
-.fancyLink a {
- font-family:arial,helvetica,sans-serif;
- font-weight:normal;
- font-size:9pt;
- color:#990000;
- text-decoration:none;
-}
-
-.fancyLink em {
- font-size:9pt;
- font-family:tahoma,arial,helvetica,sans-serif;
- font-weight:bold;
- font-style:normal;
- text-transform:none;
- color:#006600;
- text-decoration:underline;
-}
-
-.fancyLink small {
- font-family:arial,helvetica,sans-serif;
- font-size:8pt;
- font-weight:normal;
- font-style:normal;
- color:#006600;
- text-decoration:underline;
-}
-
-.fancyLink .lineDown {
- background-color:#858654;
-}
-
-.red {
- color:#FF0000;
-}
-
-.htmCode {
- color:#C00000;
- font-family:courier,monospace;
-}
-
-.cssCode {
- color:#0033FF;
- font-family:courier,monospace;
-}
-
-.green {
- color:#009933;
- font-family:courier,monospace;
-}
-
-.linksFieldset {
- width:50%;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-.bg0 {
- background-color:#787878;
-}
-
-.bg1 {
- background-color:#FFFFFF;
-}
-
-.bold {
- font-weight:bold;
-}
-
-.boldItalic {
- font-weight:bolder;
- font-style:italic;
-}
-
-.italic {
- font-style:italic;
-}
-
-.inputTitle {
- margin-top:8px;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
- color:#006600;
- text-transform:uppercase;
-}
-
-.editpadImage {
- display:inline;
- width:670px;
- border-left:2px solid #E8E8E8;
- border-top:2px solid #E8E8E8;
- border-right:2px dashed #CC0033;
- border-bottom:2px dashed #CC0033;
-}
-
-#xbitCounter {
- margin-top:7px;
- padding-top:2px;
- padding-bottom:2px;
- border: 1px solid #787878;
- background-color:#E8E8E8;
-}
-
-a {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#006600;
-}
-
-.aiTable {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#006600;
-}
-
-.aiTable th {
- font-size:11pt;
- text-align:left;
-}
-
-.aiTable td {
- text-align:justify;
-}
-
-.lineDown {
- background-color:#006600;
-}
-
-.searchBox {
- background-color:#AEFBFB;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
- border-right: 2px #666666 solid;
- border-bottom: 2px #666666 solid;
- border-top: 1px #cccccc solid;
- border-left: 1px #cccccc solid;
-}
-
-.searchBox .searchTitle {
- font-family:'Whimsy TT',fantasy,cursive;
- font-size:20pt;
- font-variant:small-caps;
- color:#000000;
-}
-
-.buttonHi {
- background-color:#3F6876;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonHi {
- width:80px;
- background-color:#3F6876;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonLo {
- width:80px;
- background-color:#AEFBFB;
- color:#000000;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.folderView {
- display:block;
- background-image:url('../images/skin-05/folder-2.gif');
-}
+/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */ + +.dummy { + font-family:verdana, arial, helvetica, sans-serif; +} + + +/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */ + +body { + margin:0px; + padding:0px; + background-color:#ECFFFF; + font-size: 100% !important; + line-height: normal !important; +} + +.headerArea { + height:120px; + margin:0px; + padding:0px; + line-height:60%; + text-align:center; + color:#FFFFFF; + background-color:#3F6876; + background-image:url('../images/skin-05/theme-back.jpg'); +} + +.headerArea a { + color:#FFFFFF; +} + +.headerArea img { + margin-left:auto; + margin-right:auto; +} + +.h1 { + font-family: verdana,arial,helvetiva,sans-serif; + font-size:15pt; + font-weight:normal; + color:#3F6876; + border:3px #3F6876 double; + padding-top:4px; + padding-bottom:6px; + width:60%; + margin:0 auto; + background-color:#AEFBFB; + text-align:center; +} + +.h2 { + margin-top:20px; + padding:0px; + font-family:Arial,Helvetica,sans-serif; + font-size:1.17em; + font-weight:normal; + color:#333333; +} + + +.h3 { + clear:both; + padding-top:16px; + padding-bottom:8px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 10pt; + color: #000066; +} + +.h3 span { + display:inline; + border-top: 1px #666666 solid; + border-bottom: 1px #666666 solid; + padding:0; + padding-top: 5px; + padding-bottom: 5px; + margin:0; +} + +.bestViewed { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:26px; + margin:0 auto; +} + +.pageMessage { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:16px; + margin:0 auto; + margin-bottom:30px; +} + +.footerArea { + clear:both; + width:100%; + text-align:center; + color:#FFFFFF; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.71em; + padding-top:0px; + background-color:#3F6876; + background-image:url('../images/skin-05/theme-back.jpg'); +} + +.footerText { + padding-top:4px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; +} + +.footerText a { + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; + text-decoration:underline; +} + +.footerText a:link {color: #FFFFFF; text-decoration: underline;} +.footerText a:visited {color: #FFFFFF; text-decoration: underline;} +.footerText a:hover {color: #FFFF00; text-decoration: underline;} +.footerText a:focus {color: #FF0000; text-decoration: underline;} +.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;} + + +/* ======= UNIVERSAL MAIN-MENU STYLES ======= */ + + +.mainMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#3F6876; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu li { + display:inline; +} + +.mainMenu a { + float:left; + width:90px; + color:#FFFFFF; + background-color:#3F6876; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #FFFFFF; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #FFFFFF; + text-align:center; + font-size:9pt; + font-weight:bold; + color:#000000; + background-color:#FFFFFF; + background-image:url('../images/skin-05/deadlink-back.gif'); +} + +.mainMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-05/hoverlink-back.gif'); +} + + +/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */ + + +.subMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#AEFBFB; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu li { + display:inline; +} + +.subMenu a { + float:left; + width:90px; + color:#000000; + background-color:#AEFBFB; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #787878; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #787878; + text-align:center; + color:#000000; + background-color:#FFFFFF; + background-image:url('../images/skin-05/deadlink-back.gif'); + background-position: 0px -1px; +} + +.subMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-05/hoverlink-back.gif'); + background-position: 0px -1px; +} + + +/* ======= SITE TABLES/BOXES STYLES ======= */ + +.siteTable { + background-color:#3F6876; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; +} + +.siteTable .bg0 { + background-color:#3F6876; + color:#FFFFFF; +} + +.siteTable .bg1 { + background-color:#ECFFFF; + color:#006600; +} + +.siteTable .bg2 { + background-color:#AEFBFB; + color:#006600; +} + +.monoTable { + background-color:#3F6876; + font-family:monospace; + font-size:10pt; +} + +.monoTable .bg0 { + background-color:#3F6876; + color:#FFFFFF; +} + +.monoTable .bg1 { + background-color:#ECFFFF; + color:#006600; +} + +.monoTable .bg2 { + background-color:#AEFBFB; + color:#006600; +} + +.themesMenu { + display:block; + margin:0; +} + +.themesMenu table { + background-color:#3F6876; + font-family:Arial,Helvetica,sans-serif; + font-size:0.7em; + text-align:center; +} + +.themesMenu .bg1 { + background-color:#FFFFFF; + color:#006600; + font-weight:bold; +} + +.themesMenu .bg1 td { + padding-top:2px; + padding-bottom:2px; + text-align:center; +} + +.normText { + font-family:Arial,Helvetica,sans-serif; + font-size:0.96em; + text-align:left; +} + +.normText a { + font-family:Arial,Helvetica,sans-serif; + font-size:11pt; + text-align:justify; + text-decoration:underline; +} + +.normText a:link {color: #006600; text-decoration: underline;} +.normText a:visited {color: #009900; text-decoration: underline;} +.normText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + + +.demoText { + font-family:Times,'Times New Roman',Palatino,serif; + font-size:0.85em; + font-weight:normal; + color: #000000; + text-align:justify; +} + +.demoText a { + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + text-decoration:underline; +} + +.demoText a:link {color: #003300; text-decoration: underline;} +.demoText a:visited {color: #003300; text-decoration: underline;} +.demoText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + +.demoTextBold { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:bold; + color: #000000; + text-align:justify; +} + +.divHeader { + text-align:center; + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.72em; + padding:5px; + color:#FFFFFF; + border:0; + background-color:#3F6876; +} + +.divData { + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-weight:normal; + font-size:0.7em; + padding:5px; + color:#000000; + background-color:#AEFBFB; +} + +.divData a { + display:inline; + font-size:1em; + color:#000000; +} + +.codeBox { + font-family:monospace,courier; + font-size:9pt; + font-weight:normal; + color: #000000; + background-color:#AEFBFB; + border:3px double #3F6876; + padding:7px; + margin-bottom:30px; +} + +.dataArea { + padding:0; + border:4px double #3F6876; + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; + line-height:140%; +} + +.dataArea .subArea1 { + padding:16px; + background-color:#AEFBFB; + color:#000033; +} + +.dataArea .subArea2 { + padding:16px; + background-color:#ECFFFF; + color:#000066; +} + +.dataArea .pseudoLink { + display:inline; + text-decoration:underline; + color:#000000; + font-size:10pt; + font-weight:normal; + cursor:pointer; +} + +.dataArea .pseudoLinkReverse { + display:inline; + color:#FFFFFF; + background-color:#3F6876; + font-size:9.4pt; + font-weight:bolder; + padding-left:4px; + padding-right:4px; +} + +.dataArea hr { + height:1px; + color:#48486E; +} + +fieldset { + display:block; + background-color:#ECFFFF; + border:2px dotted #3F6876; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + + +fieldset legend { + color: #000000; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-variant: small-caps; + font-size:11pt; + margin-top:10px; + padding: .3ex .8ex; + border:3px #3F6876 double; + font-weight: bold; + background-color:#AEFBFB; +} + +.bankHolsInner { + display:block; + background-color:#AEFBFB; + text-align:center; + margin:0 auto; + border:#3F6876 3px double; + padding:0.8em; +} + +.bankHolsTitle { + font-family:Verdana,Arial,Helvetica,sans-serif; + font-size:11pt; + font-weight:bolder; + color:#3F6876; + margin-bottom:7px; +} + +.hexRgbOuter { + float:left; + margin-top:7px; + margin-right:20px; +} + +.hexRgbInner { + display:block; + background-color:#AEFBFB; + text-align:center; + margin:0 auto; + border:#3F6876 3px double; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +.multiSearchOuter { + text-align:center; +} + +.multiSearchInner { + width:440px; + padding-left:10px; + padding-right:10px; + padding-bottom:10px; + margin-left:auto; + margin-right:auto; + background-color:#AEFBFB; + border:#3F6876 3px double; +} + +.multiSearchOuter table { + width:400px; + text-align:left; + margin-left:auto; + margin-right:auto; +} + +.lineAcross1 { + clear:both; + display:block; + background:url('../images/skin-05/line-horz-1.gif'); +} + +.lineAcross2 { + clear:both; + display:block; + background:url('../images/skin-05/line-horz-2.gif'); +} + +.lineAcross3 { + clear:both; + display:block; + background:url('../images/skin-05/line-horz-3.gif'); +} + +.lineAcross4 { + clear:both; + display:block; + background:url('../images/skin-05/line-horz-4.gif'); +} + +.siteMap a { + border: 2px solid #ECFFFF; +} + +#fixedBack { + background-image:url('../images/skin-05/fixed-back.gif'); + background-attachment:fixed; +} + +.redNote { + font-family:tahoma,arial,sans-serif; + font-size:10pt; + font-weight:bold; + font-style:italic; + color: #333333; + margin-left:15px; +} + +.fancyLink { + width:360px; + text-align:justify; + line-height:0.96em; +} + +.fancyLink a { + font-family:arial,helvetica,sans-serif; + font-weight:normal; + font-size:9pt; + color:#990000; + text-decoration:none; +} + +.fancyLink em { + font-size:9pt; + font-family:tahoma,arial,helvetica,sans-serif; + font-weight:bold; + font-style:normal; + text-transform:none; + color:#006600; + text-decoration:underline; +} + +.fancyLink small { + font-family:arial,helvetica,sans-serif; + font-size:8pt; + font-weight:normal; + font-style:normal; + color:#006600; + text-decoration:underline; +} + +.fancyLink .lineDown { + background-color:#858654; +} + +.red { + color:#FF0000; +} + +.htmCode { + color:#C00000; + font-family:courier,monospace; +} + +.cssCode { + color:#0033FF; + font-family:courier,monospace; +} + +.green { + color:#009933; + font-family:courier,monospace; +} + +.linksFieldset { + width:50%; + text-align:center; + margin-left:auto; + margin-right:auto; +} + +.bg0 { + background-color:#787878; +} + +.bg1 { + background-color:#FFFFFF; +} + +.bold { + font-weight:bold; +} + +.boldItalic { + font-weight:bolder; + font-style:italic; +} + +.italic { + font-style:italic; +} + +.inputTitle { + margin-top:8px; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; + color:#006600; + text-transform:uppercase; +} + +.editpadImage { + display:inline; + width:670px; + border-left:2px solid #E8E8E8; + border-top:2px solid #E8E8E8; + border-right:2px dashed #CC0033; + border-bottom:2px dashed #CC0033; +} + +#xbitCounter { + margin-top:7px; + padding-top:2px; + padding-bottom:2px; + border: 1px solid #787878; + background-color:#E8E8E8; +} + +a { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#006600; +} + +.aiTable { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#006600; +} + +.aiTable th { + font-size:11pt; + text-align:left; +} + +.aiTable td { + text-align:justify; +} + +.lineDown { + background-color:#006600; +} + +.searchBox { + background-color:#AEFBFB; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; + border-right: 2px #666666 solid; + border-bottom: 2px #666666 solid; + border-top: 1px #cccccc solid; + border-left: 1px #cccccc solid; +} + +.searchBox .searchTitle { + font-family:'Whimsy TT',fantasy,cursive; + font-size:20pt; + font-variant:small-caps; + color:#000000; +} + +.buttonHi { + background-color:#3F6876; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonHi { + width:80px; + background-color:#3F6876; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonLo { + width:80px; + background-color:#AEFBFB; + color:#000000; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.folderView { + display:block; + background-image:url('../images/skin-05/folder-2.gif'); +} diff --git a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-6.css b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-6.css index 1fa91ef8..376e8981 100644 --- a/docview/docs/ascii-ibm-extended-character-set_files/www-theme-6.css +++ b/docview/docs/ascii-ibm-extended-character-set_files/www-theme-6.css @@ -1,745 +1,745 @@ -/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */
-
-.dummy {
- font-family:verdana, arial, helvetica, sans-serif;
-}
-
-
-/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */
-
-body {
- margin:0px;
- padding:0px;
- background-color:#FDF3F5;
- font-size: 100% !important;
- line-height: normal !important;
-}
-
-.headerArea {
- height:120px;
- margin:0px;
- padding:0px;
- line-height:60%;
- text-align:center;
- color:#FFFFFF;
- background-color:#825963;
- background-image:url('../images/skin-06/theme-back.jpg');
-}
-
-.headerArea a {
- color:#FFFFFF;
-}
-
-.headerArea img {
- margin-left:auto;
- margin-right:auto;
-}
-
-.h1 {
- font-family: verdana,arial,helvetiva,sans-serif;
- font-size:15pt;
- font-weight:normal;
- color:#275A74;
- border:3px #825963 double;
- padding-top:4px;
- padding-bottom:6px;
- width:60%;
- margin:0 auto;
- background-color:#F7D4DB;
- text-align:center;
-}
-
-.h2 {
- margin-top:20px;
- padding:0px;
- font-family:"Comic Sans MS","VagRounded BT","Impress BT",cursive;
- font-size:1.17em;
- font-weight:normal;
- color:#275A74;
-}
-
-
-.h3 {
- clear:both;
- padding-top:16px;
- padding-bottom:8px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight: bold;
- font-style: normal;
- font-size: 10pt;
- color: #275A74;
-}
-
-.h3 span {
- display:inline;
- border-top: 1px #666666 solid;
- border-bottom: 1px #666666 solid;
- padding:0;
- padding-top: 5px;
- padding-bottom: 5px;
- margin:0;
-}
-
-.bestViewed {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:26px;
- margin:0 auto;
-}
-
-.pageMessage {
- font-family:Arial,Helvetiva,sans-serif;
- font-size:0.6em;
- font-weight:normal;
- color:#333333;
- line-height:16px;
- margin:0 auto;
- margin-bottom:30px;
-}
-
-.footerArea {
- clear:both;
- width:100%;
- text-align:center;
- color:#FFFFFF;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.71em;
- padding-top:0px;
- background-color:#825963;
- background-image:url('../images/skin-06/theme-back.jpg');
-}
-
-.footerText {
- padding-top:4px;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
-}
-
-.footerText a {
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:1em;
- color:#FFFFFF;
- text-decoration:underline;
-}
-
-.footerText a:link {color: #FFFFFF; text-decoration: underline;}
-.footerText a:visited {color: #FFFFFF; text-decoration: underline;}
-.footerText a:hover {color: #FFFF00; text-decoration: underline;}
-.footerText a:focus {color: #FF0000; text-decoration: underline;}
-.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;}
-
-
-/* ======= UNIVERSAL MAIN-MENU STYLES ======= */
-
-
-.mainMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#825963;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu li {
- display:inline;
-}
-
-.mainMenu a {
- float:left;
- width:90px;
- color:#FFFFFF;
- background-color:#825963;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #F7D4DB;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:9pt;
- font-weight:bold;
-}
-
-.mainMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #F7D4DB;
- text-align:center;
- font-size:9pt;
- font-weight:bold;
- color:#003333;
- background-color:#FFFFFF;
- background-image:url('../images/skin-06/deadlink-back.gif');
-}
-
-.mainMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-06/hoverlink-back.gif');
-}
-
-
-/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */
-
-
-.subMenu {
- float:left;
- width:100%;
- padding:0;
- margin:0;
- background-color:#F7D4DB;
- list-style-type:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu li {
- display:inline;
-}
-
-.subMenu a {
- float:left;
- width:90px;
- color:#003333;
- background-color:#F7D4DB;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #825963;
- text-align:center;
- text-decoration:none;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
-}
-
-.subMenu .deadLink {
- float:left;
- width:90px;
- padding-top:3px;
- padding-bottom:3px;
- border-right: 1px solid #825963;
- text-align:center;
- color:#003333;
- background-color:#FFFFFF;
- background-image:url('../images/skin-06/deadlink-back.gif');
- background-position: 0px -1px;
-}
-
-.subMenu a:hover{
- color:#E2393D;
- background-color:#F9F93A;
- background-image:url('../images/skin-06/hoverlink-back.gif');
- background-position: 0px -1px;
-}
-
-
-/* ======= SITE TABLES/BOXES STYLES ======= */
-
-.siteTable {
- background-color:#825963;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
-}
-
-.siteTable .bg0 {
- background-color:#825963;
- color:#FFFFFF;
-}
-
-.siteTable .bg1 {
- background-color:#FFF0FF;
- color:#003300;
-}
-
-.siteTable .bg2 {
- background-color:#F7D4DB;
- color:#003333;
-}
-
-.monoTable {
- background-color:#825963;
- font-family:monospace;
- font-size:10pt;
-}
-
-.monoTable .bg0 {
- background-color:#825963;
- color:#FFFFFF;
-}
-
-.monoTable .bg1 {
- background-color:#FFF0FF;
- color:#003300;
-}
-
-.monoTable .bg2 {
- background-color:#F7D4DB;
- color:#003333;
-}
-
-.themesMenu {
- display:block;
- margin:0;
-}
-
-.themesMenu table {
- background-color:#825963;
- font-family:Arial,Helvetica,sans-serif;
- font-size:0.7em;
- text-align:center;
-}
-
-.themesMenu .bg1 td {
- padding-top:2px;
- padding-bottom:2px;
- text-align:center;
-}
-
-.divHeader {
- text-align:center;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- font-size:0.72em;
- padding:5px;
- color:#FFFFFF;
- border:0;
- background-color:#825963;
-}
-
-.divData {
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-weight:normal;
- font-size:0.7em;
- padding:5px;
- color:#003300;
- background-color:#F7D4DB;
-}
-
-.divData a {
- display:inline;
- font-size:1em;
- color:#003300;
-}
-
-.codeBox {
- font-family:monospace,courier;
- font-size:9pt;
- font-weight:normal;
- color: #003300;
- background-color:#FFF0FF;
- border:3px double #825963;
- padding:7px;
- margin-bottom:30px;
-}
-
-.dataArea {
- padding:0;
- border:4px double #825963;
- text-align:left;
- font-family:Arial,Helvetica,sans-serif;
- font-size:10pt;
- line-height:140%;
-}
-
-.dataArea .subArea1 {
- padding:16px;
- background-color:#F7D4DB;
- color:#000033;
-}
-
-.dataArea .subArea2 {
- padding:16px;
- background-color:#FFF0FF;
- color:#000066;
-}
-
-.dataArea .pseudoLink {
- display:inline;
- text-decoration:underline;
- color:#000000;
- font-size:10pt;
- font-weight:normal;
- cursor:pointer;
-}
-
-.dataArea .pseudoLinkReverse {
- display:inline;
- color:#FFFFFF;
- background-color:#825963;
- font-size:9.4pt;
- font-weight:bolder;
- padding-left:4px;
- padding-right:4px;
-}
-
-.dataArea hr {
- height:1px;
- color:#48486E;
-}
-
-fieldset {
- display:block;
- background-color:#FDF3F5;
- border:2px dotted #825963;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-fieldset legend {
- color: #275A74;
- font-family:Geneva,Verdana,Arial,Helvetica,sans-serif;
- font-variant: small-caps;
- font-size:11pt;
- margin-top:10px;
- padding: .3ex .8ex;
- border:3px #825963 double;
- font-weight: bold;
- background-color:#F7D4DB;
-}
-
-.bankHolsInner {
- display:block;
- background-color:#F7D4DB;
- text-align:center;
- margin:0 auto;
- border:#825963 3px double;
- padding:0.8em;
-}
-
-.bankHolsTitle {
- font-family:Verdana,Arial,Helvetica,sans-serif;
- font-size:11pt;
- font-weight:bolder;
- color:#275A74;
- margin-bottom:7px;
-}
-
-.hexRgbOuter {
- float:left;
- margin-top:7px;
- margin-right:20px;
-}
-
-.hexRgbInner {
- display:block;
- background-color:#F7D4DB;
- text-align:center;
- margin:0 auto;
- border:#825963 3px double;
- margin-top:0px;;
- padding-left:1em;
- padding-right:1em;
- padding-bottom:1em;
-}
-
-.multiSearchOuter {
- text-align:center;
-}
-
-.multiSearchInner {
- width:440px;
- padding-left:10px;
- padding-right:10px;
- padding-bottom:10px;
- margin-left:auto;
- margin-right:auto;
- background-color:#F7D4DB;
- border:#825963 3px double;
-}
-
-.multiSearchOuter table {
- width:400px;
- text-align:left;
- margin-left:auto;
- margin-right:auto;
-}
-
-.lineAcross1 {
- clear:both;
- display:block;
- background:url('../images/skin-06/line-horz-1.gif');
-}
-
-.lineAcross2 {
- clear:both;
- display:block;
- background:url('../images/skin-06/line-horz-2.gif');
-}
-
-.lineAcross3 {
- clear:both;
- display:block;
- background:url('../images/skin-06/line-horz-3.gif');
-}
-
-.lineAcross4 {
- clear:both;
- display:block;
- background:url('../images/skin-06/line-horz-4.gif');
-}
-
-.normText {
- font-family:Arial,Verdana,Geneva,Helvetica,sans-serif;
- font-size:0.96em;
- text-align:justify;
-}
-
-.normText a {
- font-family:Arial,Helvetica,sans-serif;
- font-size:11pt;
- text-align:justify;
- text-decoration:underline;
-}
-
-.normText a:link {color: #275A74; text-decoration: underline;}
-.normText a:visited {color: #009900; text-decoration: underline;}
-.normText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-
-.demoText {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
- text-align:justify;
-}
-
-.demoText a {
- font-family:Arial,Helvetica,sans-serif;
- font-weight:bold;
- text-decoration:underline;
-}
-
-.demoText a:link {color: #003300; text-decoration: underline;}
-.demoText a:visited {color: #003300; text-decoration: underline;}
-.demoText a:hover {color: #CC0000; text-decoration: underline;}
-.normText a:focus {color: #00CC00; text-decoration: underline;}
-.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;}
-
-.demoTextBold {
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:bold;
- color: #000000;
- text-align:justify;
-}
-
-.siteMap a {
- border: 2px solid #FDF3F5;
-}
-
-#fixedBack {
- background-image:url('../images/skin-06/fixed-back.gif');
- background-attachment:fixed;
-}
-
-.redNote {
- font-family:tahoma,arial,sans-serif;
- font-size:10pt;
- font-weight:bold;
- font-style:italic;
- color: #CC3300;
- margin-left:15px;
-}
-
-.fancyLink {
- width:360px;
- text-align:justify;
- line-height:0.96em;
-}
-
-.fancyLink a {
- font-family:arial,helvetica,sans-serif;
- font-weight:normal;
- font-size:9pt;
- color:#990000;
- text-decoration:none;
-}
-
-.fancyLink em {
- font-size:9pt;
- font-family:tahoma,arial,helvetica,sans-serif;
- font-weight:bold;
- font-style:normal;
- text-transform:none;
- color:#275A74;
- text-decoration:underline;
-}
-
-.fancyLink small {
- font-family:arial,helvetica,sans-serif;
- font-size:8pt;
- font-weight:normal;
- font-style:normal;
- color:#275A74;
- text-decoration:underline;
-}
-
-.fancyLink .lineDown {
- background-color:#825963;
-}
-
-.red {
- color:#FF0000;
-}
-
-.htmCode {
- color:#C00000;
- font-family:courier,monospace;
-}
-
-.cssCode {
- color:#0033FF;
- font-family:courier,monospace;
-}
-
-.green {
- color:#009933;
- font-family:courier,monospace;
-}
-
-.linksFieldset {
- width:50%;
- text-align:center;
- margin-left:auto;
- margin-right:auto;
-}
-
-.bg0 {
- background-color:#825963;
-}
-
-.bg1 {
- background-color:#FFFFFF;
-}
-
-.bold {
- font-weight:bold;
-}
-
-.boldItalic {
- font-weight:bolder;
- font-style:italic;
-}
-
-.italic {
- font-style:italic;
-}
-
-.inputTitle {
- margin-top:8px;
- font-family:Arial,Helvetica,sans-serif;
- font-size:8pt;
- font-weight:bold;
- color:#275A74;
- text-transform:uppercase;
-}
-
-.editpadImage {
- display:inline;
- width:670px;
- border-left:2px solid #FDF3F5;
- border-top:2px solid #FDF3F5;
- border-right:2px dashed #CC0033;
- border-bottom:2px dashed #CC0033;
-}
-
-#xbitCounter {
- margin-top:7px;
- padding-top:2px;
- padding-bottom:2px;
- border: 1px solid #825963;
- background-color:#FDF3F5;
-}
-
-a {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#275A74;
-}
-
-.aiTable {
- font-family:arial,helvetica,sans-serif;
- font-size:9pt;
- color:#275A74;
-}
-
-.aiTable th {
- font-size:11pt;
- text-align:left;
-}
-
-.aiTable td {
- text-align:justify;
-}
-
-.lineDown {
- background-color:#275A74;
-}
-
-.searchBox {
- background-color:#F7D4DB;
- font-family:arial,helvetiva,sans-serif;
- font-size:0.8em;
- font-weight:normal;
- color: #000000;
- border-right: 2px #666666 solid;
- border-bottom: 2px #666666 solid;
- border-top: 1px #cccccc solid;
- border-left: 1px #cccccc solid;
-}
-
-.searchBox .searchTitle {
- font-family:'Whimsy TT',fantasy,cursive;
- font-size:20pt;
- font-variant:small-caps;
- color:#000000;
-}
-
-.buttonHi {
- background-color:#825963;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonHi {
- width:80px;
- background-color:#825963;
- color:#FFFFFF;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.siteButtonLo {
- width:80px;
- background-color:#F7D4DB;
- color:#003333;
- font-weight:bolder;
- font-size:9pt;
- height:23px;
-}
-
-.folderView {
- display:block;
- background-image:url('../images/skin-06/folder-2.gif');
-}
+/* ======= THIS DUMMY STYLE IS REQUIRED BECAUSE SOME EARLY BROWSERS CHEW UP THE FIRST STYLE ======= */ + +.dummy { + font-family:verdana, arial, helvetica, sans-serif; +} + + +/* ======= UNIVERSAL PAGE FURNITURE FORMATTING STYLES ======= */ + +body { + margin:0px; + padding:0px; + background-color:#FDF3F5; + font-size: 100% !important; + line-height: normal !important; +} + +.headerArea { + height:120px; + margin:0px; + padding:0px; + line-height:60%; + text-align:center; + color:#FFFFFF; + background-color:#825963; + background-image:url('../images/skin-06/theme-back.jpg'); +} + +.headerArea a { + color:#FFFFFF; +} + +.headerArea img { + margin-left:auto; + margin-right:auto; +} + +.h1 { + font-family: verdana,arial,helvetiva,sans-serif; + font-size:15pt; + font-weight:normal; + color:#275A74; + border:3px #825963 double; + padding-top:4px; + padding-bottom:6px; + width:60%; + margin:0 auto; + background-color:#F7D4DB; + text-align:center; +} + +.h2 { + margin-top:20px; + padding:0px; + font-family:"Comic Sans MS","VagRounded BT","Impress BT",cursive; + font-size:1.17em; + font-weight:normal; + color:#275A74; +} + + +.h3 { + clear:both; + padding-top:16px; + padding-bottom:8px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight: bold; + font-style: normal; + font-size: 10pt; + color: #275A74; +} + +.h3 span { + display:inline; + border-top: 1px #666666 solid; + border-bottom: 1px #666666 solid; + padding:0; + padding-top: 5px; + padding-bottom: 5px; + margin:0; +} + +.bestViewed { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:26px; + margin:0 auto; +} + +.pageMessage { + font-family:Arial,Helvetiva,sans-serif; + font-size:0.6em; + font-weight:normal; + color:#333333; + line-height:16px; + margin:0 auto; + margin-bottom:30px; +} + +.footerArea { + clear:both; + width:100%; + text-align:center; + color:#FFFFFF; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.71em; + padding-top:0px; + background-color:#825963; + background-image:url('../images/skin-06/theme-back.jpg'); +} + +.footerText { + padding-top:4px; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; +} + +.footerText a { + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:1em; + color:#FFFFFF; + text-decoration:underline; +} + +.footerText a:link {color: #FFFFFF; text-decoration: underline;} +.footerText a:visited {color: #FFFFFF; text-decoration: underline;} +.footerText a:hover {color: #FFFF00; text-decoration: underline;} +.footerText a:focus {color: #FF0000; text-decoration: underline;} +.footerText a:active {color: #FF0000; text-decoration: underline; background-color:#FFFF00;} + + +/* ======= UNIVERSAL MAIN-MENU STYLES ======= */ + + +.mainMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#825963; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu li { + display:inline; +} + +.mainMenu a { + float:left; + width:90px; + color:#FFFFFF; + background-color:#825963; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #F7D4DB; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:9pt; + font-weight:bold; +} + +.mainMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #F7D4DB; + text-align:center; + font-size:9pt; + font-weight:bold; + color:#003333; + background-color:#FFFFFF; + background-image:url('../images/skin-06/deadlink-back.gif'); +} + +.mainMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-06/hoverlink-back.gif'); +} + + +/* ======= UNIVERSAL BAR SUB-MENU STYLES ======= */ + + +.subMenu { + float:left; + width:100%; + padding:0; + margin:0; + background-color:#F7D4DB; + list-style-type:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu li { + display:inline; +} + +.subMenu a { + float:left; + width:90px; + color:#003333; + background-color:#F7D4DB; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #825963; + text-align:center; + text-decoration:none; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; +} + +.subMenu .deadLink { + float:left; + width:90px; + padding-top:3px; + padding-bottom:3px; + border-right: 1px solid #825963; + text-align:center; + color:#003333; + background-color:#FFFFFF; + background-image:url('../images/skin-06/deadlink-back.gif'); + background-position: 0px -1px; +} + +.subMenu a:hover{ + color:#E2393D; + background-color:#F9F93A; + background-image:url('../images/skin-06/hoverlink-back.gif'); + background-position: 0px -1px; +} + + +/* ======= SITE TABLES/BOXES STYLES ======= */ + +.siteTable { + background-color:#825963; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; +} + +.siteTable .bg0 { + background-color:#825963; + color:#FFFFFF; +} + +.siteTable .bg1 { + background-color:#FFF0FF; + color:#003300; +} + +.siteTable .bg2 { + background-color:#F7D4DB; + color:#003333; +} + +.monoTable { + background-color:#825963; + font-family:monospace; + font-size:10pt; +} + +.monoTable .bg0 { + background-color:#825963; + color:#FFFFFF; +} + +.monoTable .bg1 { + background-color:#FFF0FF; + color:#003300; +} + +.monoTable .bg2 { + background-color:#F7D4DB; + color:#003333; +} + +.themesMenu { + display:block; + margin:0; +} + +.themesMenu table { + background-color:#825963; + font-family:Arial,Helvetica,sans-serif; + font-size:0.7em; + text-align:center; +} + +.themesMenu .bg1 td { + padding-top:2px; + padding-bottom:2px; + text-align:center; +} + +.divHeader { + text-align:center; + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + font-size:0.72em; + padding:5px; + color:#FFFFFF; + border:0; + background-color:#825963; +} + +.divData { + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-weight:normal; + font-size:0.7em; + padding:5px; + color:#003300; + background-color:#F7D4DB; +} + +.divData a { + display:inline; + font-size:1em; + color:#003300; +} + +.codeBox { + font-family:monospace,courier; + font-size:9pt; + font-weight:normal; + color: #003300; + background-color:#FFF0FF; + border:3px double #825963; + padding:7px; + margin-bottom:30px; +} + +.dataArea { + padding:0; + border:4px double #825963; + text-align:left; + font-family:Arial,Helvetica,sans-serif; + font-size:10pt; + line-height:140%; +} + +.dataArea .subArea1 { + padding:16px; + background-color:#F7D4DB; + color:#000033; +} + +.dataArea .subArea2 { + padding:16px; + background-color:#FFF0FF; + color:#000066; +} + +.dataArea .pseudoLink { + display:inline; + text-decoration:underline; + color:#000000; + font-size:10pt; + font-weight:normal; + cursor:pointer; +} + +.dataArea .pseudoLinkReverse { + display:inline; + color:#FFFFFF; + background-color:#825963; + font-size:9.4pt; + font-weight:bolder; + padding-left:4px; + padding-right:4px; +} + +.dataArea hr { + height:1px; + color:#48486E; +} + +fieldset { + display:block; + background-color:#FDF3F5; + border:2px dotted #825963; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +fieldset legend { + color: #275A74; + font-family:Geneva,Verdana,Arial,Helvetica,sans-serif; + font-variant: small-caps; + font-size:11pt; + margin-top:10px; + padding: .3ex .8ex; + border:3px #825963 double; + font-weight: bold; + background-color:#F7D4DB; +} + +.bankHolsInner { + display:block; + background-color:#F7D4DB; + text-align:center; + margin:0 auto; + border:#825963 3px double; + padding:0.8em; +} + +.bankHolsTitle { + font-family:Verdana,Arial,Helvetica,sans-serif; + font-size:11pt; + font-weight:bolder; + color:#275A74; + margin-bottom:7px; +} + +.hexRgbOuter { + float:left; + margin-top:7px; + margin-right:20px; +} + +.hexRgbInner { + display:block; + background-color:#F7D4DB; + text-align:center; + margin:0 auto; + border:#825963 3px double; + margin-top:0px;; + padding-left:1em; + padding-right:1em; + padding-bottom:1em; +} + +.multiSearchOuter { + text-align:center; +} + +.multiSearchInner { + width:440px; + padding-left:10px; + padding-right:10px; + padding-bottom:10px; + margin-left:auto; + margin-right:auto; + background-color:#F7D4DB; + border:#825963 3px double; +} + +.multiSearchOuter table { + width:400px; + text-align:left; + margin-left:auto; + margin-right:auto; +} + +.lineAcross1 { + clear:both; + display:block; + background:url('../images/skin-06/line-horz-1.gif'); +} + +.lineAcross2 { + clear:both; + display:block; + background:url('../images/skin-06/line-horz-2.gif'); +} + +.lineAcross3 { + clear:both; + display:block; + background:url('../images/skin-06/line-horz-3.gif'); +} + +.lineAcross4 { + clear:both; + display:block; + background:url('../images/skin-06/line-horz-4.gif'); +} + +.normText { + font-family:Arial,Verdana,Geneva,Helvetica,sans-serif; + font-size:0.96em; + text-align:justify; +} + +.normText a { + font-family:Arial,Helvetica,sans-serif; + font-size:11pt; + text-align:justify; + text-decoration:underline; +} + +.normText a:link {color: #275A74; text-decoration: underline;} +.normText a:visited {color: #009900; text-decoration: underline;} +.normText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.normText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + + +.demoText { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; + text-align:justify; +} + +.demoText a { + font-family:Arial,Helvetica,sans-serif; + font-weight:bold; + text-decoration:underline; +} + +.demoText a:link {color: #003300; text-decoration: underline;} +.demoText a:visited {color: #003300; text-decoration: underline;} +.demoText a:hover {color: #CC0000; text-decoration: underline;} +.normText a:focus {color: #00CC00; text-decoration: underline;} +.demoText a:active {color: #FF0000; text-decoration: underline; background-color:#000000;} + +.demoTextBold { + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:bold; + color: #000000; + text-align:justify; +} + +.siteMap a { + border: 2px solid #FDF3F5; +} + +#fixedBack { + background-image:url('../images/skin-06/fixed-back.gif'); + background-attachment:fixed; +} + +.redNote { + font-family:tahoma,arial,sans-serif; + font-size:10pt; + font-weight:bold; + font-style:italic; + color: #CC3300; + margin-left:15px; +} + +.fancyLink { + width:360px; + text-align:justify; + line-height:0.96em; +} + +.fancyLink a { + font-family:arial,helvetica,sans-serif; + font-weight:normal; + font-size:9pt; + color:#990000; + text-decoration:none; +} + +.fancyLink em { + font-size:9pt; + font-family:tahoma,arial,helvetica,sans-serif; + font-weight:bold; + font-style:normal; + text-transform:none; + color:#275A74; + text-decoration:underline; +} + +.fancyLink small { + font-family:arial,helvetica,sans-serif; + font-size:8pt; + font-weight:normal; + font-style:normal; + color:#275A74; + text-decoration:underline; +} + +.fancyLink .lineDown { + background-color:#825963; +} + +.red { + color:#FF0000; +} + +.htmCode { + color:#C00000; + font-family:courier,monospace; +} + +.cssCode { + color:#0033FF; + font-family:courier,monospace; +} + +.green { + color:#009933; + font-family:courier,monospace; +} + +.linksFieldset { + width:50%; + text-align:center; + margin-left:auto; + margin-right:auto; +} + +.bg0 { + background-color:#825963; +} + +.bg1 { + background-color:#FFFFFF; +} + +.bold { + font-weight:bold; +} + +.boldItalic { + font-weight:bolder; + font-style:italic; +} + +.italic { + font-style:italic; +} + +.inputTitle { + margin-top:8px; + font-family:Arial,Helvetica,sans-serif; + font-size:8pt; + font-weight:bold; + color:#275A74; + text-transform:uppercase; +} + +.editpadImage { + display:inline; + width:670px; + border-left:2px solid #FDF3F5; + border-top:2px solid #FDF3F5; + border-right:2px dashed #CC0033; + border-bottom:2px dashed #CC0033; +} + +#xbitCounter { + margin-top:7px; + padding-top:2px; + padding-bottom:2px; + border: 1px solid #825963; + background-color:#FDF3F5; +} + +a { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#275A74; +} + +.aiTable { + font-family:arial,helvetica,sans-serif; + font-size:9pt; + color:#275A74; +} + +.aiTable th { + font-size:11pt; + text-align:left; +} + +.aiTable td { + text-align:justify; +} + +.lineDown { + background-color:#275A74; +} + +.searchBox { + background-color:#F7D4DB; + font-family:arial,helvetiva,sans-serif; + font-size:0.8em; + font-weight:normal; + color: #000000; + border-right: 2px #666666 solid; + border-bottom: 2px #666666 solid; + border-top: 1px #cccccc solid; + border-left: 1px #cccccc solid; +} + +.searchBox .searchTitle { + font-family:'Whimsy TT',fantasy,cursive; + font-size:20pt; + font-variant:small-caps; + color:#000000; +} + +.buttonHi { + background-color:#825963; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonHi { + width:80px; + background-color:#825963; + color:#FFFFFF; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.siteButtonLo { + width:80px; + background-color:#F7D4DB; + color:#003333; + font-weight:bolder; + font-size:9pt; + height:23px; +} + +.folderView { + display:block; + background-image:url('../images/skin-06/folder-2.gif'); +} diff --git a/docview/src/docview.rc b/docview/src/docview.rc index f68bb7b2..87597a3f 100644 --- a/docview/src/docview.rc +++ b/docview/src/docview.rc @@ -1,29 +1,29 @@ -MAINICON ICON "../images/docview-48x48.ico"
-
-1 VERSIONINFO
-FILEVERSION 0, 8, 0, 0
-PRODUCTVERSION 0, 8, 0, 0
-FILEFLAGSMASK 0
-FILEOS 0x40000
-FILETYPE 1
-{
- BLOCK "StringFileInfo"
- {
- BLOCK "040904E4"
- {
- VALUE "CompanyName", "fpGUI Toolkit"
- VALUE "FileDescription", "fpGUI's INF Documentation Viewer"
- VALUE "FileVersion", "0.8.0"
- VALUE "InternalName", "docview"
- VALUE "LegalCopyright", "GNU Public License"
- VALUE "OriginalFilename", "docview"
- VALUE "ProductName", "fpGUI Toolkit"
- VALUE "ProductVersion", "0.8.0"
- }
- }
- BLOCK "VarFileInfo"
- {
- VALUE "Translation", 0x409, 0x4E4
- }
-}
-
+MAINICON ICON "../images/docview-48x48.ico" + +1 VERSIONINFO +FILEVERSION 0, 8, 0, 0 +PRODUCTVERSION 0, 8, 0, 0 +FILEFLAGSMASK 0 +FILEOS 0x40000 +FILETYPE 1 +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName", "fpGUI Toolkit" + VALUE "FileDescription", "fpGUI's INF Documentation Viewer" + VALUE "FileVersion", "0.8.0" + VALUE "InternalName", "docview" + VALUE "LegalCopyright", "GNU Public License" + VALUE "OriginalFilename", "docview" + VALUE "ProductName", "fpGUI Toolkit" + VALUE "ProductVersion", "0.8.0" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x409, 0x4E4 + } +} + diff --git a/examples/apps/ide/src/sha1.pas b/examples/apps/ide/src/sha1.pas index a1f16392..f849f9ad 100644 --- a/examples/apps/ide/src/sha1.pas +++ b/examples/apps/ide/src/sha1.pas @@ -1,503 +1,503 @@ -// ============================================================================
-// D5-implementation of "US Secure Hash Algorithm 1 (SHA1)" (RFC3174)
-// Copyright (c) 2001, Juergen Haible.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-// ============================================================================
-
-{------------------------------------------------------------------------------
-Update by F. Piette for ICS (http://www.overbyte.be)
-Jan 10, 2004 Defined uint32_t as Cardinal instead of LongInt
-------------------------------------------------------------------------------}
-
-
-unit Sha1;
-
-{$mode objfpc}{$H+}
-{$R-}
-{$Q-}
-
-interface
-
-uses SysUtils, Classes;
-
-const
- shaSuccess = 0;
- shaNull = 1;
- shaInputTooLong = 2;
- shaStateError = 3;
- SHA1HashSize = 20;
-
-type
- uint32_t = Cardinal; // unsigned 32 bit integer
- uint8_t = Byte; // unsigned 8 bit integer (i.e., unsigned char)
- int_least16_t = LongInt; // integer of >= 16 bits
-
- SHA1Digest = array[0..SHA1HashSize-1] of Char;
- SHA1DigestString = AnsiString; // string containing 20 chars
-
- // This structure will hold context information for the SHA-1
- // hashing operation
- SHA1Context = record
- Intermediate_Hash: array[0..SHA1HashSize div 4-1] of uint32_t; // Message Digest
- Length_Low : uint32_t; // Message length in bits
- Length_High: uint32_t; // Message length in bits
- Message_Block_Index: int_least16_t; // Index into message block array
- Message_Block: array[0..63] of uint8_t; // 512-bit message blocks
- Computed: Integer; // Is the digest computed?
- Corrupted: Integer; // Is the message digest corrupted?
- end;
-
-function SHA1Reset ( var context : SHA1Context ): Integer;
-function SHA1Input ( var context : SHA1Context;
- message_array : PChar;
- length : Cardinal ): Integer;
-function SHA1Result( var context : SHA1Context;
- var Message_Digest: SHA1Digest ): Integer;
-
-function SHA1ofStr ( const s: String ): SHA1DigestString;
-function SHA1ofBuf ( const buf; buflen: Integer ): SHA1DigestString;
-function SHA1ofStream( const strm: TStream ): SHA1DigestString;
-
-function SHA1toHex( const digest: SHA1DigestString ): String;
-
-procedure HMAC_SHA1( const Data; DataLen: Integer;
- const Key; KeyLen : Integer;
- out Digest : SHA1Digest );
-function HMAC_SHA1_EX( const Data: String;
- const Key : String ): String; //overload;
-
-implementation
-
-// Define the SHA1 circular left shift macro
-function SHA1CircularShift( const bits, word: uint32_t ): uint32_t;
-begin
- Result := (((word) shl (bits)) or ((word) shr (32-(bits))));
-end;
-
-// This function will process the next 512 bits of the message
-// stored in the Message_Block array.
-procedure SHA1ProcessMessageBlock( var context: SHA1Context );
-const K: array[0..3] of uint32_t = ( //* Constants defined in SHA-1 */
- $5A827999,
- $6ED9EBA1,
- $8F1BBCDC,
- $CA62C1D6
- );
-var
- t: Integer; //* Loop counter */
- temp: uint32_t; //* Temporary word value */
- W: array[0..79] of uint32_t; //* Word sequence */
- A, B, C, D, E: uint32_t; //* Word buffers */
-begin
-
- // Initialize the first 16 words in the array W
- for t := 0 to 15 do begin
- W[t] := context.Message_Block[t * 4 ] shl 24
- or context.Message_Block[t * 4 + 1] shl 16
- or context.Message_Block[t * 4 + 2] shl 8
- or context.Message_Block[t * 4 + 3];
- end;
-
- for t := 16 to 79 do begin
- W[t] := SHA1CircularShift(1,W[t-3] xor W[t-8] xor W[t-14] xor W[t-16]);
- end;
-
- A := context.Intermediate_Hash[0];
- B := context.Intermediate_Hash[1];
- C := context.Intermediate_Hash[2];
- D := context.Intermediate_Hash[3];
- E := context.Intermediate_Hash[4];
-
- for t := 0 to 19 do begin
- temp := SHA1CircularShift(5,A) +
- ((B and C) or ((not B) and D)) + E + W[t] + K[0];
- E := D;
- D := C;
- C := SHA1CircularShift(30,B);
- B := A;
- A := temp;
- end;
-
- for t := 20 to 39 do begin
- temp := SHA1CircularShift(5,A) + (B xor C xor D) + E + W[t] + K[1];
- E := D;
- D := C;
- C := SHA1CircularShift(30,B);
- B := A;
- A := temp;
- end;
-
- for t := 40 to 59 do begin
- temp := SHA1CircularShift(5,A) +
- ((B and C) or (B and D) or (C and D)) + E + W[t] + K[2];
- E := D;
- D := C;
- C := SHA1CircularShift(30,B);
- B := A;
- A := temp;
- end;
-
- for t := 60 to 79 do begin
- temp := SHA1CircularShift(5,A) + (B xor C xor D) + E + W[t] + K[3];
- E := D;
- D := C;
- C := SHA1CircularShift(30,B);
- B := A;
- A := temp;
- end;
-
- inc( context.Intermediate_Hash[0], A );
- inc( context.Intermediate_Hash[1], B );
- inc( context.Intermediate_Hash[2], C );
- inc( context.Intermediate_Hash[3], D );
- inc( context.Intermediate_Hash[4], E );
-
- context.Message_Block_Index := 0;
-end;
-
-// According to the standard, the message must be padded to an even
-// 512 bits. The first padding bit must be a '1'. The last 64
-// bits represent the length of the original message. All bits in
-// between should be 0. This function will pad the message
-// according to those rules by filling the Message_Block array
-// accordingly. It will also call the ProcessMessageBlock function
-// provided appropriately. When it returns, it can be assumed that
-// the message digest has been computed.
-procedure SHA1PadMessage( var context: SHA1Context );
-begin
- (*
- * Check to see if the current message block is too small to hold
- * the initial padding bits and length. If so, we will pad the
- * block, process it, and then continue padding into a second
- * block.
- *)
- if (context.Message_Block_Index > 55) then begin
- context.Message_Block[context.Message_Block_Index] := $80;
- inc( context.Message_Block_Index );
- while (context.Message_Block_Index < 64) do begin
- context.Message_Block[context.Message_Block_Index] := 0;
- inc( context.Message_Block_Index );
- end;
-
- SHA1ProcessMessageBlock( context );
-
- while (context.Message_Block_Index < 56) do begin
- context.Message_Block[context.Message_Block_Index] := 0;
- inc( context.Message_Block_Index );
- end;
- end else begin
- context.Message_Block[context.Message_Block_Index] := $80;
- inc( context.Message_Block_Index );
- while (context.Message_Block_Index < 56) do begin
- context.Message_Block[context.Message_Block_Index] := 0;
- inc( context.Message_Block_Index );
- end;
- end;
-
- // Store the message length as the last 8 octets
- context.Message_Block[56] := context.Length_High shr 24;
- context.Message_Block[57] := context.Length_High shr 16;
- context.Message_Block[58] := context.Length_High shr 8;
- context.Message_Block[59] := context.Length_High;
- context.Message_Block[60] := context.Length_Low shr 24;
- context.Message_Block[61] := context.Length_Low shr 16;
- context.Message_Block[62] := context.Length_Low shr 8;
- context.Message_Block[63] := context.Length_Low;
-
- SHA1ProcessMessageBlock(context);
-end;
-
-// This function will initialize the SHA1Context in preparation
-// for computing a new SHA1 message digest.
-function SHA1Reset( var context: SHA1Context ): Integer;
-begin
- // if (context=0) then begin Result:=shaNull; exit end;
-
- context.Length_Low := 0;
- context.Length_High := 0;
- context.Message_Block_Index := 0;
-
- context.Intermediate_Hash[0] := $67452301;
- context.Intermediate_Hash[1] := $EFCDAB89;
- context.Intermediate_Hash[2] := $98BADCFE;
- context.Intermediate_Hash[3] := $10325476;
- context.Intermediate_Hash[4] := $C3D2E1F0;
-
- context.Computed := 0;
- context.Corrupted := 0;
-
- Result := shaSuccess;
-end;
-
-// This function will return the 160-bit message digest into the
-// Message_Digest array provided by the caller.
-function SHA1Result( var context: SHA1Context;
- var Message_Digest: SHA1Digest ): Integer;
-var i: Integer;
-begin
- // if (!context || !Message_Digest) then begin Result:=shaNull; exit end;
-
- if (context.Corrupted<>0) then begin Result:=context.Corrupted; exit end;
-
- if (context.Computed=0) then begin
- SHA1PadMessage( context );
- for i:=0 to 63 do begin
- //* message may be sensitive, clear it out */
- context.Message_Block[i] := 0;
- end;
- context.Length_Low := 0; //* and clear length */
- context.Length_High := 0;
- context.Computed := 1;
- end;
-
- for i := 0 to SHA1HashSize-1 do begin
- Message_Digest[i] := chr( context.Intermediate_Hash[i shr 2]
- shr ( 8 * ( 3 - ( uint32_t(i) and $03 ) ) ) );
- end;
-
- Result := shaSuccess;
-end;
-
-// This function accepts an array of octets as the next portion
-// of the message.
-function SHA1Input( var context: SHA1Context;
- message_array: PChar;
- length: Cardinal ): Integer;
-begin
- if (length=0) then begin Result:=shaSuccess; exit end;
- // if (!context || !message_array) then begin Result:=shaNull; exit end;
- if (message_array=nil) then begin Result:=shaNull; exit end;
-
- if (context.Computed<>0) then begin
- context.Corrupted := shaStateError;
- Result := shaStateError;
- exit;
- end;
-
- if (context.Corrupted<>0) then begin
- Result := context.Corrupted;
- exit;
- end;
-
- while (length>0) and (context.Corrupted=0) do begin
- context.Message_Block[context.Message_Block_Index] := (ord(message_array^) and $FF);
- inc( context.Message_Block_Index );
-
- inc( context.Length_Low, 8 );
- if (context.Length_Low = 0) then begin
- inc( context.Length_High );
- if (context.Length_High = 0) then begin
- // Message is too long
- context.Corrupted := 1;
- end;
- end;
-
- if (context.Message_Block_Index = 64) then begin
- SHA1ProcessMessageBlock(context);
- end;
-
- inc( message_array );
- dec( length );
- end;
-
- Result := shaSuccess;
-end;
-
-// ----------------------------------------------------------------------------
-
-// returns SHA1 digest of given string
-function SHA1ofStr( const s: String ): SHA1DigestString;
-var context: SHA1Context;
- digest : SHA1Digest;
-begin
- SHA1Reset ( context);
- SHA1Input ( context, PChar( @s[1] ), length(s) );
- SHA1Result( context, digest );
- SetLength( Result, sizeof(digest) );
- Move( digest, Result[1], sizeof(digest) );
-end;
-
-
-// returns SHA1 digest of given buffer
-function SHA1ofBuf( const buf; buflen: Integer ): SHA1DigestString;
-var context: SHA1Context;
- digest : SHA1Digest;
-begin
- SHA1Reset ( context);
- SHA1Input ( context, PChar( buf ), buflen );
- SHA1Result( context, digest );
- SetLength( Result, sizeof(digest) );
- Move( digest, Result[1], sizeof(digest) );
-end;
-
-
-// returns SHA1 digest of given stream
-function SHA1ofStream( const strm: TStream ): SHA1DigestString;
-var context: SHA1Context;
- digest : SHA1Digest;
- buf: array[0..4095] of char;
- buflen: Integer;
-begin
- SHA1Reset ( context);
- strm.Position := 0;
- repeat
- buflen := strm.Read( buf[0], 4096 );
- if buflen>0 then SHA1Input ( context, buf, buflen );
- until buflen<4096;
- SHA1Result( context, digest );
- SetLength( Result, sizeof(digest) );
- Move( digest, Result[1], sizeof(digest) );
-end;
-
-
-// converts SHA1 digest into a hex-string
-
-function SHA1toHex( const digest: SHA1DigestString ): String;
-var i: Integer;
-begin
- Result := '';
- for i:=1 to length(digest) do Result := Result + inttohex( ord( digest[i] ), 2 );
- Result := LowerCase( Result );
-end;
-
-// ----------------------------------------------------------------------------
-
-// Keyed SHA1 (HMAC-SHA1), RFC 2104
-
-
-procedure HMAC_SHA1(const Data; DataLen: Integer;
- const Key; KeyLen : Integer;
- out Digest : SHA1Digest );
-var k_ipad, k_opad: array[0..64] of Byte;
- Context: SHA1Context;
- i : Integer;
-begin
- // clear pads
- FillChar( k_ipad, sizeof(k_ipad), 0 );
- FillChar( k_opad, sizeof(k_ipad), 0 );
-
- if KeyLen > 64 then begin
- // if key is longer than 64 bytes reset it to key=SHA1(key)
- SHA1Reset ( Context);
- SHA1Input ( Context, PChar(@Key), KeyLen );
- SHA1Result( Context, Digest );
- // store key in pads
- Move( Digest, k_ipad, SHA1HashSize );
- Move( Digest, k_opad, SHA1HashSize );
- end else begin
- // store key in pads
- Move( Key, k_ipad, KeyLen );
- Move( Key, k_opad, KeyLen );
- end;
-
- // XOR key with ipad and opad values
- for i:=0 to 63 do begin
- k_ipad[i] := k_ipad[i] xor $36;
- k_opad[i] := k_opad[i] xor $5c;
- end;
-
- // perform inner SHA1
- SHA1Reset ( Context );
- SHA1Input ( Context, PChar(@k_ipad[0]), 64 );
- SHA1Input ( Context, PChar(@Data), DataLen );
- SHA1Result( Context, Digest );
-
- // perform outer SHA1
- SHA1Reset ( Context );
- SHA1Input ( Context, PChar(@k_opad[0]), 64 );
- SHA1Input ( Context, Digest, SHA1HashSize );
- SHA1Result( Context, Digest );
-end;
-
-function HMAC_SHA1_EX( const Data: String;
- const Key : String ): String;
-var Digest: SHA1Digest;
-begin
- HMAC_SHA1( Data[1], length(Data), Key[1], length(Key), Digest );
- SetLength( Result, SHA1HashSize );
- Move( digest[0], Result[1], SHA1HashSize );
-end;
-
-// ----------------------------------------------------------------------------
-
-{
-SHA1 test suit:
-procedure TForm1.Button1Click(Sender: TObject);
-const TEST1 = 'abc';
- TEST2a = 'abcdbcdecdefdefgefghfghighijhi';
- TEST2b = 'jkijkljklmklmnlmnomnopnopq';
- TEST2 = TEST2a + TEST2b;
- TEST3 = 'a';
- TEST4a = '01234567012345670123456701234567';
- TEST4b = '01234567012345670123456701234567';
- TEST4 = TEST4a + TEST4b;
- testarray: array[0..3] of String = ( TEST1, TEST2, TEST3, TEST4 );
- repeatcount: array[0..3] of Integer = ( 1, 1, 1000000, 10 );
- resultarray: array [0..3] of String = (
- 'A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D',
- '84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1',
- '34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F',
- 'DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52' );
-var sha: SHA1Context;
- i, j, err: Integer;
- Message_Digest: SHA1Digest;
- s: String;
-begin
- for j := 0 to 3 do begin
- ListBox1.Items.Add( Format( 'Test %d: %d, "%s"',
- [ j+1, repeatcount[j], testarray[j] ] ) );
-
- err := SHA1Reset(sha);
- if (err<>0) then begin
- ListBox1.Items.Add( Format( 'SHA1Reset Error %d.', [err] ) );
- break; //* out of for j loop */
- end;
-
- for i := 0 to repeatcount[j]-1 do begin
- err := SHA1Input( sha, @testarray[j][1], length(testarray[j]) );
- if (err<>0) then begin
- ListBox1.Items.Add( Format('SHA1Input Error %d.', [err] ) );
- break; //* out of for i loop */
- end;
- end;
-
- err := SHA1Result(sha, Message_Digest);
- if (err<>0) then begin
- ListBox1.Items.Add( Format(
- 'SHA1Result Error %d, could not compute message digest.', [err] ) );
- end else begin
- s := '';
- for i := 0 to 19 do begin
- s := s + Format('%02X ', [ ord(Message_Digest[i]) ] );
- end;
- ListBox1.Items.Add( 'Result: ' + s );
- end;
-
- ListBox1.Items.Add( 'Wanted: ' + Format('%s', [resultarray[j]] ) );
- end;
-end;
-
-HMAC-SHA1 test suite of RFC 2202:
-procedure TForm1.Button3Click(Sender: TObject);
-end;
-}
-
-end.
-
+// ============================================================================ +// D5-implementation of "US Secure Hash Algorithm 1 (SHA1)" (RFC3174) +// Copyright (c) 2001, Juergen Haible. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// ============================================================================ + +{------------------------------------------------------------------------------ +Update by F. Piette for ICS (http://www.overbyte.be) +Jan 10, 2004 Defined uint32_t as Cardinal instead of LongInt +------------------------------------------------------------------------------} + + +unit Sha1; + +{$mode objfpc}{$H+} +{$R-} +{$Q-} + +interface + +uses SysUtils, Classes; + +const + shaSuccess = 0; + shaNull = 1; + shaInputTooLong = 2; + shaStateError = 3; + SHA1HashSize = 20; + +type + uint32_t = Cardinal; // unsigned 32 bit integer + uint8_t = Byte; // unsigned 8 bit integer (i.e., unsigned char) + int_least16_t = LongInt; // integer of >= 16 bits + + SHA1Digest = array[0..SHA1HashSize-1] of Char; + SHA1DigestString = AnsiString; // string containing 20 chars + + // This structure will hold context information for the SHA-1 + // hashing operation + SHA1Context = record + Intermediate_Hash: array[0..SHA1HashSize div 4-1] of uint32_t; // Message Digest + Length_Low : uint32_t; // Message length in bits + Length_High: uint32_t; // Message length in bits + Message_Block_Index: int_least16_t; // Index into message block array + Message_Block: array[0..63] of uint8_t; // 512-bit message blocks + Computed: Integer; // Is the digest computed? + Corrupted: Integer; // Is the message digest corrupted? + end; + +function SHA1Reset ( var context : SHA1Context ): Integer; +function SHA1Input ( var context : SHA1Context; + message_array : PChar; + length : Cardinal ): Integer; +function SHA1Result( var context : SHA1Context; + var Message_Digest: SHA1Digest ): Integer; + +function SHA1ofStr ( const s: String ): SHA1DigestString; +function SHA1ofBuf ( const buf; buflen: Integer ): SHA1DigestString; +function SHA1ofStream( const strm: TStream ): SHA1DigestString; + +function SHA1toHex( const digest: SHA1DigestString ): String; + +procedure HMAC_SHA1( const Data; DataLen: Integer; + const Key; KeyLen : Integer; + out Digest : SHA1Digest ); +function HMAC_SHA1_EX( const Data: String; + const Key : String ): String; //overload; + +implementation + +// Define the SHA1 circular left shift macro +function SHA1CircularShift( const bits, word: uint32_t ): uint32_t; +begin + Result := (((word) shl (bits)) or ((word) shr (32-(bits)))); +end; + +// This function will process the next 512 bits of the message +// stored in the Message_Block array. +procedure SHA1ProcessMessageBlock( var context: SHA1Context ); +const K: array[0..3] of uint32_t = ( //* Constants defined in SHA-1 */ + $5A827999, + $6ED9EBA1, + $8F1BBCDC, + $CA62C1D6 + ); +var + t: Integer; //* Loop counter */ + temp: uint32_t; //* Temporary word value */ + W: array[0..79] of uint32_t; //* Word sequence */ + A, B, C, D, E: uint32_t; //* Word buffers */ +begin + + // Initialize the first 16 words in the array W + for t := 0 to 15 do begin + W[t] := context.Message_Block[t * 4 ] shl 24 + or context.Message_Block[t * 4 + 1] shl 16 + or context.Message_Block[t * 4 + 2] shl 8 + or context.Message_Block[t * 4 + 3]; + end; + + for t := 16 to 79 do begin + W[t] := SHA1CircularShift(1,W[t-3] xor W[t-8] xor W[t-14] xor W[t-16]); + end; + + A := context.Intermediate_Hash[0]; + B := context.Intermediate_Hash[1]; + C := context.Intermediate_Hash[2]; + D := context.Intermediate_Hash[3]; + E := context.Intermediate_Hash[4]; + + for t := 0 to 19 do begin + temp := SHA1CircularShift(5,A) + + ((B and C) or ((not B) and D)) + E + W[t] + K[0]; + E := D; + D := C; + C := SHA1CircularShift(30,B); + B := A; + A := temp; + end; + + for t := 20 to 39 do begin + temp := SHA1CircularShift(5,A) + (B xor C xor D) + E + W[t] + K[1]; + E := D; + D := C; + C := SHA1CircularShift(30,B); + B := A; + A := temp; + end; + + for t := 40 to 59 do begin + temp := SHA1CircularShift(5,A) + + ((B and C) or (B and D) or (C and D)) + E + W[t] + K[2]; + E := D; + D := C; + C := SHA1CircularShift(30,B); + B := A; + A := temp; + end; + + for t := 60 to 79 do begin + temp := SHA1CircularShift(5,A) + (B xor C xor D) + E + W[t] + K[3]; + E := D; + D := C; + C := SHA1CircularShift(30,B); + B := A; + A := temp; + end; + + inc( context.Intermediate_Hash[0], A ); + inc( context.Intermediate_Hash[1], B ); + inc( context.Intermediate_Hash[2], C ); + inc( context.Intermediate_Hash[3], D ); + inc( context.Intermediate_Hash[4], E ); + + context.Message_Block_Index := 0; +end; + +// According to the standard, the message must be padded to an even +// 512 bits. The first padding bit must be a '1'. The last 64 +// bits represent the length of the original message. All bits in +// between should be 0. This function will pad the message +// according to those rules by filling the Message_Block array +// accordingly. It will also call the ProcessMessageBlock function +// provided appropriately. When it returns, it can be assumed that +// the message digest has been computed. +procedure SHA1PadMessage( var context: SHA1Context ); +begin + (* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + *) + if (context.Message_Block_Index > 55) then begin + context.Message_Block[context.Message_Block_Index] := $80; + inc( context.Message_Block_Index ); + while (context.Message_Block_Index < 64) do begin + context.Message_Block[context.Message_Block_Index] := 0; + inc( context.Message_Block_Index ); + end; + + SHA1ProcessMessageBlock( context ); + + while (context.Message_Block_Index < 56) do begin + context.Message_Block[context.Message_Block_Index] := 0; + inc( context.Message_Block_Index ); + end; + end else begin + context.Message_Block[context.Message_Block_Index] := $80; + inc( context.Message_Block_Index ); + while (context.Message_Block_Index < 56) do begin + context.Message_Block[context.Message_Block_Index] := 0; + inc( context.Message_Block_Index ); + end; + end; + + // Store the message length as the last 8 octets + context.Message_Block[56] := context.Length_High shr 24; + context.Message_Block[57] := context.Length_High shr 16; + context.Message_Block[58] := context.Length_High shr 8; + context.Message_Block[59] := context.Length_High; + context.Message_Block[60] := context.Length_Low shr 24; + context.Message_Block[61] := context.Length_Low shr 16; + context.Message_Block[62] := context.Length_Low shr 8; + context.Message_Block[63] := context.Length_Low; + + SHA1ProcessMessageBlock(context); +end; + +// This function will initialize the SHA1Context in preparation +// for computing a new SHA1 message digest. +function SHA1Reset( var context: SHA1Context ): Integer; +begin + // if (context=0) then begin Result:=shaNull; exit end; + + context.Length_Low := 0; + context.Length_High := 0; + context.Message_Block_Index := 0; + + context.Intermediate_Hash[0] := $67452301; + context.Intermediate_Hash[1] := $EFCDAB89; + context.Intermediate_Hash[2] := $98BADCFE; + context.Intermediate_Hash[3] := $10325476; + context.Intermediate_Hash[4] := $C3D2E1F0; + + context.Computed := 0; + context.Corrupted := 0; + + Result := shaSuccess; +end; + +// This function will return the 160-bit message digest into the +// Message_Digest array provided by the caller. +function SHA1Result( var context: SHA1Context; + var Message_Digest: SHA1Digest ): Integer; +var i: Integer; +begin + // if (!context || !Message_Digest) then begin Result:=shaNull; exit end; + + if (context.Corrupted<>0) then begin Result:=context.Corrupted; exit end; + + if (context.Computed=0) then begin + SHA1PadMessage( context ); + for i:=0 to 63 do begin + //* message may be sensitive, clear it out */ + context.Message_Block[i] := 0; + end; + context.Length_Low := 0; //* and clear length */ + context.Length_High := 0; + context.Computed := 1; + end; + + for i := 0 to SHA1HashSize-1 do begin + Message_Digest[i] := chr( context.Intermediate_Hash[i shr 2] + shr ( 8 * ( 3 - ( uint32_t(i) and $03 ) ) ) ); + end; + + Result := shaSuccess; +end; + +// This function accepts an array of octets as the next portion +// of the message. +function SHA1Input( var context: SHA1Context; + message_array: PChar; + length: Cardinal ): Integer; +begin + if (length=0) then begin Result:=shaSuccess; exit end; + // if (!context || !message_array) then begin Result:=shaNull; exit end; + if (message_array=nil) then begin Result:=shaNull; exit end; + + if (context.Computed<>0) then begin + context.Corrupted := shaStateError; + Result := shaStateError; + exit; + end; + + if (context.Corrupted<>0) then begin + Result := context.Corrupted; + exit; + end; + + while (length>0) and (context.Corrupted=0) do begin + context.Message_Block[context.Message_Block_Index] := (ord(message_array^) and $FF); + inc( context.Message_Block_Index ); + + inc( context.Length_Low, 8 ); + if (context.Length_Low = 0) then begin + inc( context.Length_High ); + if (context.Length_High = 0) then begin + // Message is too long + context.Corrupted := 1; + end; + end; + + if (context.Message_Block_Index = 64) then begin + SHA1ProcessMessageBlock(context); + end; + + inc( message_array ); + dec( length ); + end; + + Result := shaSuccess; +end; + +// ---------------------------------------------------------------------------- + +// returns SHA1 digest of given string +function SHA1ofStr( const s: String ): SHA1DigestString; +var context: SHA1Context; + digest : SHA1Digest; +begin + SHA1Reset ( context); + SHA1Input ( context, PChar( @s[1] ), length(s) ); + SHA1Result( context, digest ); + SetLength( Result, sizeof(digest) ); + Move( digest, Result[1], sizeof(digest) ); +end; + + +// returns SHA1 digest of given buffer +function SHA1ofBuf( const buf; buflen: Integer ): SHA1DigestString; +var context: SHA1Context; + digest : SHA1Digest; +begin + SHA1Reset ( context); + SHA1Input ( context, PChar( buf ), buflen ); + SHA1Result( context, digest ); + SetLength( Result, sizeof(digest) ); + Move( digest, Result[1], sizeof(digest) ); +end; + + +// returns SHA1 digest of given stream +function SHA1ofStream( const strm: TStream ): SHA1DigestString; +var context: SHA1Context; + digest : SHA1Digest; + buf: array[0..4095] of char; + buflen: Integer; +begin + SHA1Reset ( context); + strm.Position := 0; + repeat + buflen := strm.Read( buf[0], 4096 ); + if buflen>0 then SHA1Input ( context, buf, buflen ); + until buflen<4096; + SHA1Result( context, digest ); + SetLength( Result, sizeof(digest) ); + Move( digest, Result[1], sizeof(digest) ); +end; + + +// converts SHA1 digest into a hex-string + +function SHA1toHex( const digest: SHA1DigestString ): String; +var i: Integer; +begin + Result := ''; + for i:=1 to length(digest) do Result := Result + inttohex( ord( digest[i] ), 2 ); + Result := LowerCase( Result ); +end; + +// ---------------------------------------------------------------------------- + +// Keyed SHA1 (HMAC-SHA1), RFC 2104 + + +procedure HMAC_SHA1(const Data; DataLen: Integer; + const Key; KeyLen : Integer; + out Digest : SHA1Digest ); +var k_ipad, k_opad: array[0..64] of Byte; + Context: SHA1Context; + i : Integer; +begin + // clear pads + FillChar( k_ipad, sizeof(k_ipad), 0 ); + FillChar( k_opad, sizeof(k_ipad), 0 ); + + if KeyLen > 64 then begin + // if key is longer than 64 bytes reset it to key=SHA1(key) + SHA1Reset ( Context); + SHA1Input ( Context, PChar(@Key), KeyLen ); + SHA1Result( Context, Digest ); + // store key in pads + Move( Digest, k_ipad, SHA1HashSize ); + Move( Digest, k_opad, SHA1HashSize ); + end else begin + // store key in pads + Move( Key, k_ipad, KeyLen ); + Move( Key, k_opad, KeyLen ); + end; + + // XOR key with ipad and opad values + for i:=0 to 63 do begin + k_ipad[i] := k_ipad[i] xor $36; + k_opad[i] := k_opad[i] xor $5c; + end; + + // perform inner SHA1 + SHA1Reset ( Context ); + SHA1Input ( Context, PChar(@k_ipad[0]), 64 ); + SHA1Input ( Context, PChar(@Data), DataLen ); + SHA1Result( Context, Digest ); + + // perform outer SHA1 + SHA1Reset ( Context ); + SHA1Input ( Context, PChar(@k_opad[0]), 64 ); + SHA1Input ( Context, Digest, SHA1HashSize ); + SHA1Result( Context, Digest ); +end; + +function HMAC_SHA1_EX( const Data: String; + const Key : String ): String; +var Digest: SHA1Digest; +begin + HMAC_SHA1( Data[1], length(Data), Key[1], length(Key), Digest ); + SetLength( Result, SHA1HashSize ); + Move( digest[0], Result[1], SHA1HashSize ); +end; + +// ---------------------------------------------------------------------------- + +{ +SHA1 test suit: +procedure TForm1.Button1Click(Sender: TObject); +const TEST1 = 'abc'; + TEST2a = 'abcdbcdecdefdefgefghfghighijhi'; + TEST2b = 'jkijkljklmklmnlmnomnopnopq'; + TEST2 = TEST2a + TEST2b; + TEST3 = 'a'; + TEST4a = '01234567012345670123456701234567'; + TEST4b = '01234567012345670123456701234567'; + TEST4 = TEST4a + TEST4b; + testarray: array[0..3] of String = ( TEST1, TEST2, TEST3, TEST4 ); + repeatcount: array[0..3] of Integer = ( 1, 1, 1000000, 10 ); + resultarray: array [0..3] of String = ( + 'A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D', + '84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1', + '34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F', + 'DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52' ); +var sha: SHA1Context; + i, j, err: Integer; + Message_Digest: SHA1Digest; + s: String; +begin + for j := 0 to 3 do begin + ListBox1.Items.Add( Format( 'Test %d: %d, "%s"', + [ j+1, repeatcount[j], testarray[j] ] ) ); + + err := SHA1Reset(sha); + if (err<>0) then begin + ListBox1.Items.Add( Format( 'SHA1Reset Error %d.', [err] ) ); + break; //* out of for j loop */ + end; + + for i := 0 to repeatcount[j]-1 do begin + err := SHA1Input( sha, @testarray[j][1], length(testarray[j]) ); + if (err<>0) then begin + ListBox1.Items.Add( Format('SHA1Input Error %d.', [err] ) ); + break; //* out of for i loop */ + end; + end; + + err := SHA1Result(sha, Message_Digest); + if (err<>0) then begin + ListBox1.Items.Add( Format( + 'SHA1Result Error %d, could not compute message digest.', [err] ) ); + end else begin + s := ''; + for i := 0 to 19 do begin + s := s + Format('%02X ', [ ord(Message_Digest[i]) ] ); + end; + ListBox1.Items.Add( 'Result: ' + s ); + end; + + ListBox1.Items.Add( 'Wanted: ' + Format('%s', [resultarray[j]] ) ); + end; +end; + +HMAC-SHA1 test suite of RFC 2202: +procedure TForm1.Button3Click(Sender: TObject); +end; +} + +end. + diff --git a/extras/contributed/ats/atstable.ats b/extras/contributed/ats/atstable.ats index 412fa3c5..9167100e 100644 --- a/extras/contributed/ats/atstable.ats +++ b/extras/contributed/ats/atstable.ats @@ -1,218 +1,218 @@ -rsLanguage:
- EN="English"
- RU="Русский"
- AF="Afrikaans"
-rsOK:
- EN="OK"
- RU="OK"
- AF="Goed"
-rsCancel:
- EN="Cancel"
- RU="Отмена"
- AF="Kanseleer"
-rsHelp:
- EN="Help"
- RU="Справка"
- AF="Help"
-rsOpen:
- EN="Open"
- RU="Открыть"
- AF="Maak oop"
-rsSave:
- EN="Save"
- RU="Сохранить"
- AF="Stoor"
-rsCreate:
- EN="Create"
- RU="Создать"
-rsChange:
- EN="Change"
- RU="Изменить"
-rsFind:
- EN="Find"
- RU="Найти"
-rsSearch:
- EN="Search"
- RU="Поиск"
-rsReplace:
- EN="Replace"
- RU="Заменить"
-rsConfirm:
- EN="Confirm"
- RU="Подтвердить"
-rsAll:
- EN="All"
- RU="Все"
-rsSelect:
- EN="Select"
- RU="Выбрать"
-rsYes:
- EN="Yes"
- RU="Да"
-rsNo:
- EN="No"
- RU="Нет"
- AF="Nee"
-rsAbort:
- EN="Abort"
- RU="Прервать"
-rsRetry:
- EN="Retry"
- RU="Повторить"
-rsIgnore:
- EN="Ignore"
- RU="Пропустить"
-rsClose:
- EN="Close"
- RU="Закрыть"
-rsInsert:
- EN="Insert"
- RU="Вставка"
-rsEdit:
- EN="Edit"
- RU="Редактировать"
-rsDelete:
- EN="Delete"
- RU="Удалить"
-rsExit:
- EN="Exit"
- RU="Выход"
-rsYesToAll:
- EN="Yes to All"
- RU="Да для всех"
-rsNoToAll:
- EN="No to All"
- RU="Нет для всех"
-rsCut:
- EN="Cut"
- RU="Вырезать"
-rsCopy:
- EN="Copy"
- RU="Копировать"
-rsPaste:
- EN="Paste"
- RU="Вставить"
-rsError:
- EN="Error"
-rsCriticalError:
- EN="Critical Error"
-rsInformation:
- EN="Information"
-rsConfirmation:
- EN="Confirmation"
-rsWarning:
- EN="Warning"
-rsMessage:
- EN="Message"
-rsAbout:
- EN="About %s"
-rsAllFiles:
- EN="All Files"
-rsCreateDirectory:
- EN="Create directory"
-rsEnterNewDirectory:
- EN="Enter new directory name"
-rsCannotCreateDir:
- EN="Cannot create directory"
-rsSelectAFont:
- EN="Select a font"
-rsName:
- EN="Name"
-rsCollection:
- EN="Collection"
-rsSize:
- EN="Size"
-rsStyle:
- EN="Style"
-rsItalic:
- EN="Italic"
-rsBold:
- EN="Bold"
-rsUnderScore:
- EN="UnderScore"
-rsTypeface:
- EN="Typeface"
-rsAntiAliasing:
- EN="Anti aliasing"
-rsExampleText:
- EN="Example Text"
-rsCollectionAllFonts:
- EN="All Fonts"
-rsCollectionRecentlyUsed:
- EN="Recently Used"
-rsCollectionFavourites:
- EN="Favourites"
-rsCollectionFixedWidth:
- EN="Fixed Width"
-rsCollectionSans:
- EN="Sans"
-rsCollectionSerif:
- EN="Serif"
-rsCollectionFontAliases:
- EN="Font Aliases"
-rsOpenAFile:
- EN="Open a file"
-rsFileName:
- EN="Filename"
-rsFileType:
- EN="Type of file"
-rsDrive:
- EN="Drive"
-rsFiles:
- EN="Files"
-rsDirectories:
- EN="Directories"
-rsShowHidden:
- EN="Show hidden files"
-rsFileSelection:
- EN="File Selection"
-rsFileModifiedTime:
- EN="Mod. Time"
-rsFileAttributes:
- EN="Attributes"
-rsFileRights:
- EN="Rights"
-rsFileOwner:
- EN="Owner"
-rsFileGroup:
- EN="Group"
-rsSaveAFile:
- EN="Save file as"
-rsErrListMustBeEmpty:
- EN="List must be empty"
-rsErrCouldNotOpenDir:
- EN="Could not open the directory <%s>"
-rsErrItemOfWrongType:
- EN="Item is not of <%s> type!"
-rsErrFailedToCreateDir:
- EN="Failed to create the directory <%s>"
-rsErrNotAssigned:
- EN="<%s> not assigned"
-rsShortMon:
- EN="Mon"
-rsShortTue:
- EN="Tue"
-rsShortWed:
- EN="Wed"
-rsShortThu:
- EN="Thu"
-rsShortFri:
- EN="Fri"
-rsShortSat:
- EN="Sat"
-rsShortSun:
- EN="Sun"
-rsLongMon:
- EN="Monday"
-rsLongTue:
- EN="Tuesday"
-rsLongWed:
- EN="Wednesday"
-rsLongThu:
- EN="Thursday"
-rsLongFri:
- EN="Friday"
-rsLongSat:
- EN="Saturday"
-rsLongSun:
- EN="Sunday"
+rsLanguage: + EN="English" + RU="Русский" + AF="Afrikaans" +rsOK: + EN="OK" + RU="OK" + AF="Goed" +rsCancel: + EN="Cancel" + RU="Отмена" + AF="Kanseleer" +rsHelp: + EN="Help" + RU="Справка" + AF="Help" +rsOpen: + EN="Open" + RU="Открыть" + AF="Maak oop" +rsSave: + EN="Save" + RU="Сохранить" + AF="Stoor" +rsCreate: + EN="Create" + RU="Создать" +rsChange: + EN="Change" + RU="Изменить" +rsFind: + EN="Find" + RU="Найти" +rsSearch: + EN="Search" + RU="Поиск" +rsReplace: + EN="Replace" + RU="Заменить" +rsConfirm: + EN="Confirm" + RU="Подтвердить" +rsAll: + EN="All" + RU="Все" +rsSelect: + EN="Select" + RU="Выбрать" +rsYes: + EN="Yes" + RU="Да" +rsNo: + EN="No" + RU="Нет" + AF="Nee" +rsAbort: + EN="Abort" + RU="Прервать" +rsRetry: + EN="Retry" + RU="Повторить" +rsIgnore: + EN="Ignore" + RU="Пропустить" +rsClose: + EN="Close" + RU="Закрыть" +rsInsert: + EN="Insert" + RU="Вставка" +rsEdit: + EN="Edit" + RU="Редактировать" +rsDelete: + EN="Delete" + RU="Удалить" +rsExit: + EN="Exit" + RU="Выход" +rsYesToAll: + EN="Yes to All" + RU="Да для всех" +rsNoToAll: + EN="No to All" + RU="Нет для всех" +rsCut: + EN="Cut" + RU="Вырезать" +rsCopy: + EN="Copy" + RU="Копировать" +rsPaste: + EN="Paste" + RU="Вставить" +rsError: + EN="Error" +rsCriticalError: + EN="Critical Error" +rsInformation: + EN="Information" +rsConfirmation: + EN="Confirmation" +rsWarning: + EN="Warning" +rsMessage: + EN="Message" +rsAbout: + EN="About %s" +rsAllFiles: + EN="All Files" +rsCreateDirectory: + EN="Create directory" +rsEnterNewDirectory: + EN="Enter new directory name" +rsCannotCreateDir: + EN="Cannot create directory" +rsSelectAFont: + EN="Select a font" +rsName: + EN="Name" +rsCollection: + EN="Collection" +rsSize: + EN="Size" +rsStyle: + EN="Style" +rsItalic: + EN="Italic" +rsBold: + EN="Bold" +rsUnderScore: + EN="UnderScore" +rsTypeface: + EN="Typeface" +rsAntiAliasing: + EN="Anti aliasing" +rsExampleText: + EN="Example Text" +rsCollectionAllFonts: + EN="All Fonts" +rsCollectionRecentlyUsed: + EN="Recently Used" +rsCollectionFavourites: + EN="Favourites" +rsCollectionFixedWidth: + EN="Fixed Width" +rsCollectionSans: + EN="Sans" +rsCollectionSerif: + EN="Serif" +rsCollectionFontAliases: + EN="Font Aliases" +rsOpenAFile: + EN="Open a file" +rsFileName: + EN="Filename" +rsFileType: + EN="Type of file" +rsDrive: + EN="Drive" +rsFiles: + EN="Files" +rsDirectories: + EN="Directories" +rsShowHidden: + EN="Show hidden files" +rsFileSelection: + EN="File Selection" +rsFileModifiedTime: + EN="Mod. Time" +rsFileAttributes: + EN="Attributes" +rsFileRights: + EN="Rights" +rsFileOwner: + EN="Owner" +rsFileGroup: + EN="Group" +rsSaveAFile: + EN="Save file as" +rsErrListMustBeEmpty: + EN="List must be empty" +rsErrCouldNotOpenDir: + EN="Could not open the directory <%s>" +rsErrItemOfWrongType: + EN="Item is not of <%s> type!" +rsErrFailedToCreateDir: + EN="Failed to create the directory <%s>" +rsErrNotAssigned: + EN="<%s> not assigned" +rsShortMon: + EN="Mon" +rsShortTue: + EN="Tue" +rsShortWed: + EN="Wed" +rsShortThu: + EN="Thu" +rsShortFri: + EN="Fri" +rsShortSat: + EN="Sat" +rsShortSun: + EN="Sun" +rsLongMon: + EN="Monday" +rsLongTue: + EN="Tuesday" +rsLongWed: + EN="Wednesday" +rsLongThu: + EN="Thursday" +rsLongFri: + EN="Friday" +rsLongSat: + EN="Saturday" +rsLongSun: + EN="Sunday" diff --git a/extras/contributed/ats/atstable.csv b/extras/contributed/ats/atstable.csv index 84dffa92..5037b0ea 100644 --- a/extras/contributed/ats/atstable.csv +++ b/extras/contributed/ats/atstable.csv @@ -1,92 +1,92 @@ -"ATSF1","EN","RU","AF"
-"rsLanguage","English","Русский","Afrikaans"
-"rsOK","OK","OK","Goed"
-"rsCancel","Cancel","Отмена","Kanseleer"
-"rsHelp","Help","Справка","Help"
-"rsOpen","Open","Открыть","Maak oop"
-"rsSave","Save","Сохранить","Stoor"
-"rsCreate","Create","Создать",""
-"rsChange","Change","Изменить",""
-"rsFind","Find","Найти",""
-"rsSearch","Search","Поиск",""
-"rsReplace","Replace","Заменить",""
-"rsConfirm","Confirm","Подтвердить",""
-"rsAll","All","Все",""
-"rsSelect","Select","Выбрать",""
-"rsYes","Yes","Да",""
-"rsNo","No","Нет","Nee"
-"rsAbort","Abort","Прервать",""
-"rsRetry","Retry","Повторить",""
-"rsIgnore","Ignore","Пропустить",""
-"rsClose","Close","Закрыть",""
-"rsInsert","Insert","Вставка",""
-"rsEdit","Edit","Редактировать",""
-"rsDelete","Delete","Удалить",""
-"rsExit","Exit","Выход",""
-"rsYesToAll","Yes to All","Да для всех",""
-"rsNoToAll","No to All","Нет для всех",""
-"rsCut","Cut","Вырезать",""
-"rsCopy","Copy","Копировать",""
-"rsPaste","Paste","Вставить",""
-"rsError","Error","",""
-"rsCriticalError","Critical Error","",""
-"rsInformation","Information","",""
-"rsConfirmation","Confirmation","",""
-"rsWarning","Warning","",""
-"rsMessage","Message","",""
-"rsAbout","About %s","",""
-"rsAllFiles","All Files","",""
-"rsCreateDirectory","Create directory","",""
-"rsEnterNewDirectory","Enter new directory name","",""
-"rsCannotCreateDir","Cannot create directory","",""
-"rsSelectAFont","Select a font","",""
-"rsName","Name","",""
-"rsCollection","Collection","",""
-"rsSize","Size","",""
-"rsStyle","Style","",""
-"rsItalic","Italic","",""
-"rsBold","Bold","",""
-"rsUnderScore","UnderScore","",""
-"rsTypeface","Typeface","",""
-"rsAntiAliasing","Anti aliasing","",""
-"rsExampleText","Example Text","",""
-"rsCollectionAllFonts","All Fonts","",""
-"rsCollectionRecentlyUsed","Recently Used","",""
-"rsCollectionFavourites","Favourites","",""
-"rsCollectionFixedWidth","Fixed Width","",""
-"rsCollectionSans","Sans","",""
-"rsCollectionSerif","Serif","",""
-"rsCollectionFontAliases","Font Aliases","",""
-"rsOpenAFile","Open a file","",""
-"rsFileName","Filename","",""
-"rsFileType","Type of file","",""
-"rsDrive","Drive","",""
-"rsFiles","Files","",""
-"rsDirectories","Directories","",""
-"rsShowHidden","Show hidden files","",""
-"rsFileSelection","File Selection","",""
-"rsFileModifiedTime","Mod. Time","",""
-"rsFileAttributes","Attributes","",""
-"rsFileRights","Rights","",""
-"rsFileOwner","Owner","",""
-"rsFileGroup","Group","",""
-"rsSaveAFile","Save file as","",""
-"rsErrListMustBeEmpty","List must be empty","",""
-"rsErrCouldNotOpenDir","Could not open the directory <%s>","",""
-"rsErrItemOfWrongType","Item is not of <%s> type!","",""
-"rsErrFailedToCreateDir","Failed to create the directory <%s>","",""
-"rsErrNotAssigned","<%s> not assigned","",""
-"rsShortMon","Mon","",""
-"rsShortTue","Tue","",""
-"rsShortWed","Wed","",""
-"rsShortThu","Thu","",""
-"rsShortFri","Fri","",""
-"rsShortSat","Sat","",""
-"rsShortSun","Sun","",""
-"rsLongMon","Monday","",""
-"rsLongTue","Tuesday","",""
-"rsLongWed","Wednesday","",""
-"rsLongThu","Thursday","",""
-"rsLongFri","Friday","",""
-"rsLongSat","Saturday","",""
+"ATSF1","EN","RU","AF" +"rsLanguage","English","Русский","Afrikaans" +"rsOK","OK","OK","Goed" +"rsCancel","Cancel","Отмена","Kanseleer" +"rsHelp","Help","Справка","Help" +"rsOpen","Open","Открыть","Maak oop" +"rsSave","Save","Сохранить","Stoor" +"rsCreate","Create","Создать","" +"rsChange","Change","Изменить","" +"rsFind","Find","Найти","" +"rsSearch","Search","Поиск","" +"rsReplace","Replace","Заменить","" +"rsConfirm","Confirm","Подтвердить","" +"rsAll","All","Все","" +"rsSelect","Select","Выбрать","" +"rsYes","Yes","Да","" +"rsNo","No","Нет","Nee" +"rsAbort","Abort","Прервать","" +"rsRetry","Retry","Повторить","" +"rsIgnore","Ignore","Пропустить","" +"rsClose","Close","Закрыть","" +"rsInsert","Insert","Вставка","" +"rsEdit","Edit","Редактировать","" +"rsDelete","Delete","Удалить","" +"rsExit","Exit","Выход","" +"rsYesToAll","Yes to All","Да для всех","" +"rsNoToAll","No to All","Нет для всех","" +"rsCut","Cut","Вырезать","" +"rsCopy","Copy","Копировать","" +"rsPaste","Paste","Вставить","" +"rsError","Error","","" +"rsCriticalError","Critical Error","","" +"rsInformation","Information","","" +"rsConfirmation","Confirmation","","" +"rsWarning","Warning","","" +"rsMessage","Message","","" +"rsAbout","About %s","","" +"rsAllFiles","All Files","","" +"rsCreateDirectory","Create directory","","" +"rsEnterNewDirectory","Enter new directory name","","" +"rsCannotCreateDir","Cannot create directory","","" +"rsSelectAFont","Select a font","","" +"rsName","Name","","" +"rsCollection","Collection","","" +"rsSize","Size","","" +"rsStyle","Style","","" +"rsItalic","Italic","","" +"rsBold","Bold","","" +"rsUnderScore","UnderScore","","" +"rsTypeface","Typeface","","" +"rsAntiAliasing","Anti aliasing","","" +"rsExampleText","Example Text","","" +"rsCollectionAllFonts","All Fonts","","" +"rsCollectionRecentlyUsed","Recently Used","","" +"rsCollectionFavourites","Favourites","","" +"rsCollectionFixedWidth","Fixed Width","","" +"rsCollectionSans","Sans","","" +"rsCollectionSerif","Serif","","" +"rsCollectionFontAliases","Font Aliases","","" +"rsOpenAFile","Open a file","","" +"rsFileName","Filename","","" +"rsFileType","Type of file","","" +"rsDrive","Drive","","" +"rsFiles","Files","","" +"rsDirectories","Directories","","" +"rsShowHidden","Show hidden files","","" +"rsFileSelection","File Selection","","" +"rsFileModifiedTime","Mod. Time","","" +"rsFileAttributes","Attributes","","" +"rsFileRights","Rights","","" +"rsFileOwner","Owner","","" +"rsFileGroup","Group","","" +"rsSaveAFile","Save file as","","" +"rsErrListMustBeEmpty","List must be empty","","" +"rsErrCouldNotOpenDir","Could not open the directory <%s>","","" +"rsErrItemOfWrongType","Item is not of <%s> type!","","" +"rsErrFailedToCreateDir","Failed to create the directory <%s>","","" +"rsErrNotAssigned","<%s> not assigned","","" +"rsShortMon","Mon","","" +"rsShortTue","Tue","","" +"rsShortWed","Wed","","" +"rsShortThu","Thu","","" +"rsShortFri","Fri","","" +"rsShortSat","Sat","","" +"rsShortSun","Sun","","" +"rsLongMon","Monday","","" +"rsLongTue","Tuesday","","" +"rsLongWed","Wednesday","","" +"rsLongThu","Thursday","","" +"rsLongFri","Friday","","" +"rsLongSat","Saturday","","" "rsLongSun","Sunday","",""
\ No newline at end of file diff --git a/extras/contributed/ats/atstable.inc b/extras/contributed/ats/atstable.inc index 3a06923e..ade8c733 100644 --- a/extras/contributed/ats/atstable.inc +++ b/extras/contributed/ats/atstable.inc @@ -1,291 +1,291 @@ -array[1..288] of string = (
- 'rsLanguage:'
- ,' EN="English"'
- ,' RU="Русский"'
- ,' HU="Magyar"'
- ,' AF="Afrikaans"'
- ,'rsOK:'
- ,' EN="OK"'
- ,' RU="OK"'
- ,' HU="OK"'
- ,' AF="Goed"'
- ,'rsCancel:'
- ,' EN="Cancel"'
- ,' RU="Отмена"'
- ,' HU="Mégse"'
- ,' AF="Kanselleer"'
- ,'rsHelp:'
- ,' EN="Help"'
- ,' RU="Справка"'
- ,' HU="Segítség"'
- ,'rsOpen:'
- ,' EN="Open"'
- ,' RU="Открыть"'
- ,' HU="Megnyitás"'
- ,'rsSave:'
- ,' EN="Save"'
- ,' RU="Сохранить"'
- ,' HU="Mentés"'
- ,' AF="Stoor"'
- ,'rsCreate:'
- ,' EN="Create"'
- ,' RU="Создать"'
- ,' HU="Létrehoz"'
- ,'rsChange:'
- ,' EN="Change"'
- ,' RU="Изменить"'
- ,' HU="Változtat"'
- ,' AF="Verander"'
- ,'rsFind:'
- ,' EN="Find"'
- ,' RU="Найти"'
- ,' HU="Talál"'
- ,' AF="Vind"'
- ,'rsSearch:'
- ,' EN="Search"'
- ,' RU="Поиск"'
- ,' HU="Keres"'
- ,' AF="Soek"'
- ,'rsReplace:'
- ,' EN="Replace"'
- ,' RU="Заменить"'
- ,' HU="Cserél"'
- ,' AF="Vervang"'
- ,'rsConfirm:'
- ,' EN="Confirm"'
- ,' RU="Подтвердить"'
- ,' HU="Jóváhagy"'
- ,'rsAll:'
- ,' EN="All"'
- ,' RU="Все"'
- ,' HU="Mind"'
- ,' AF="Alles"'
- ,'rsSelect:'
- ,' EN="Select"'
- ,' RU="Выбрать"'
- ,' HU="Kiválaszt"'
- ,'rsYes:'
- ,' EN="Yes"'
- ,' RU="Да"'
- ,' HU="Igen"'
- ,' AF="Ja"'
- ,'rsNo:'
- ,' EN="No"'
- ,' RU="Нет"'
- ,' HU="Nem"'
- ,' AF="Nee"'
- ,'rsAbort:'
- ,' EN="Abort"'
- ,' RU="Прервать"'
- ,' HU="Megszakít"'
- ,'rsRetry:'
- ,' EN="Retry"'
- ,' RU="Повторить"'
- ,' HU="Újra"'
- ,'rsIgnore:'
- ,' EN="Ignore"'
- ,' RU="Пропустить"'
- ,' HU="Kihagy"'
- ,' AF="Ignoreer"'
- ,'rsClose:'
- ,' EN="Close"'
- ,' RU="Закрыть"'
- ,' HU="Bezár"'
- ,' AF="Sluit"'
- ,'rsInsert:'
- ,' EN="Insert"'
- ,' RU="Вставка"'
- ,' HU="Beszúr"'
- ,'rsEdit:'
- ,' EN="Edit"'
- ,' RU="Редактировать"'
- ,' HU="Szerkeszt"'
- ,'rsDelete:'
- ,' EN="Delete"'
- ,' RU="Удалить"'
- ,' HU="Töröl"'
- ,'rsExit:'
- ,' EN="Exit"'
- ,' RU="Выход"'
- ,' HU="Kilép"'
- ,' AF="Verlaat"'
- ,'rsYesToAll:'
- ,' EN="Yes to All"'
- ,' RU="Да для всех"'
- ,' HU="Mindre igen"'
- ,'rsNoToAll:'
- ,' EN="No to All"'
- ,' RU="Нет для всех"'
- ,' HU="Mindre nem"'
- ,'rsCut:'
- ,' EN="Cut"'
- ,' RU="Вырезать"'
- ,' HU="Kivág"'
- ,'rsCopy:'
- ,' EN="Copy"'
- ,' RU="Копировать"'
- ,' HU="Másol"'
- ,'rsPaste:'
- ,' EN="Paste"'
- ,' RU="Вставить"'
- ,' HU="Beilleszt"'
- ,'rsError:'
- ,' EN="Error"'
- ,' HU="Hiba"'
- ,'rsCriticalError:'
- ,' EN="Critical Error"'
- ,' HU="Kritikus hiba"'
- ,'rsInformation:'
- ,' EN="Information"'
- ,' HU="Információ"'
- ,'rsConfirmation:'
- ,' EN="Confirmation"'
- ,' HU="Megerősítés"'
- ,'rsWarning:'
- ,' EN="Warning"'
- ,' HU="Figyelmeztetés"'
- ,'rsMessage:'
- ,' EN="Message"'
- ,' HU="Üzenet"'
- ,'rsAbout:'
- ,' EN="About %s"'
- ,' HU="About %s"'
- ,'rsAllFiles:'
- ,' EN="All Files"'
- ,' HU="Összes fájl"'
- ,'rsCreateDirectory:'
- ,' EN="Create directory"'
- ,' HU="Könyvtár létrehozása"'
- ,'rsEnterNewDirectory:'
- ,' EN="Enter new directory name"'
- ,'rsCannotCreateDir:'
- ,' EN="Cannot create directory"'
- ,'rsSelectAFont:'
- ,' EN="Select a font"'
- ,'rsName:'
- ,' EN="Name"'
- ,' AF="Naam"'
- ,'rsCollection:'
- ,' EN="Collection"'
- ,'rsSize:'
- ,' EN="Size"'
- ,' AF="Goote"'
- ,'rsStyle:'
- ,' EN="Style"'
- ,' AF="Steil"'
- ,'rsItalic:'
- ,' EN="Italic"'
- ,'rsBold:'
- ,' EN="Bold"'
- ,'rsUnderScore:'
- ,' EN="UnderScore"'
- ,'rsTypeface:'
- ,' EN="Typeface"'
- ,'rsAntiAliasing:'
- ,' EN="Anti aliasing"'
- ,'rsExampleText:'
- ,' EN="Example Text"'
- ,' AF="Voorbeeld Teks"'
- ,'rsCollectionAllFonts:'
- ,' EN="All Fonts"'
- ,'rsCollectionRecentlyUsed:'
- ,' EN="Recently Used"'
- ,'rsCollectionFavourites:'
- ,' EN="Favourites"'
- ,'rsCollectionFixedWidth:'
- ,' EN="Fixed Width"'
- ,'rsCollectionSans:'
- ,' EN="Sans"'
- ,'rsCollectionSerif:'
- ,' EN="Serif"'
- ,'rsCollectionFontAliases:'
- ,' EN="Font Aliases"'
- ,'rsOpenAFile:'
- ,' EN="Open a file"'
- ,'rsFileName:'
- ,' EN="Filename"'
- ,'rsFileType:'
- ,' EN="Type of file"'
- ,'rsDrive:'
- ,' EN="Drive"'
- ,'rsFiles:'
- ,' EN="Files"'
- ,'rsDirectories:'
- ,' EN="Directories"'
- ,'rsShowHidden:'
- ,' EN="Show hidden files"'
- ,'rsFileSelection:'
- ,' EN="File Selection"'
- ,'rsFileModifiedTime:'
- ,' EN="Mod. Time"'
- ,'rsFileAttributes:'
- ,' EN="Attributes"'
- ,'rsFileRights:'
- ,' EN="Rights"'
- ,'rsFileOwner:'
- ,' EN="Owner"'
- ,'rsFileGroup:'
- ,' EN="Group"'
- ,'rsSaveAFile:'
- ,' EN="Save file as"'
- ,'rsErrListMustBeEmpty:'
- ,' EN="List must be empty"'
- ,'rsErrCouldNotOpenDir:'
- ,' EN="Could not open the directory <%s>"'
- ,'rsErrItemOfWrongType:'
- ,' EN="Item is not of <%s> type!"'
- ,'rsErrFailedToCreateDir:'
- ,' EN="Failed to create the directory <%s>"'
- ,'rsErrNotAssigned:'
- ,' EN="<%s> not assigned"'
- ,'rsShortMon:'
- ,' EN="Mon"'
- ,' HU="H"'
- ,'rsShortTue:'
- ,' EN="Tue"'
- ,' HU="K"'
- ,'rsShortWed:'
- ,' EN="Wed"'
- ,' HU="Sz"'
- ,'rsShortThu:'
- ,' EN="Thu"'
- ,' HU="Cs"'
- ,'rsShortFri:'
- ,' EN="Fri"'
- ,' HU="P"'
- ,'rsShortSat:'
- ,' EN="Sat"'
- ,' HU="Szo"'
- ,'rsShortSun:'
- ,' EN="Sun"'
- ,' HU="V"'
- ,'rsLongMon:'
- ,' EN="Monday"'
- ,' HU="Hétfő"'
- ,' AF="Maandag"'
- ,'rsLongTue:'
- ,' EN="Tuesday"'
- ,' HU="Kedd"'
- ,' AF="Dinsdag"'
- ,'rsLongWed:'
- ,' EN="Wednesday"'
- ,' HU="Szerda"'
- ,' AF="Woensdag"'
- ,'rsLongThu:'
- ,' EN="Thursday"'
- ,' HU="Csütörtök"'
- ,' AF="Donderdag"'
- ,'rsLongFri:'
- ,' EN="Friday"'
- ,' HU="Péntek"'
- ,' AF="Vrydag"'
- ,'rsLongSat:'
- ,' EN="Saturday"'
- ,' HU="Szombat"'
- ,' AF="Saterdag"'
- ,'rsLongSun:'
- ,' EN="Sunday"'
- ,' HU="Vasárnap"'
- ,' AF="Sondag"'
-
-);
+array[1..288] of string = ( + 'rsLanguage:' + ,' EN="English"' + ,' RU="Русский"' + ,' HU="Magyar"' + ,' AF="Afrikaans"' + ,'rsOK:' + ,' EN="OK"' + ,' RU="OK"' + ,' HU="OK"' + ,' AF="Goed"' + ,'rsCancel:' + ,' EN="Cancel"' + ,' RU="Отмена"' + ,' HU="Mégse"' + ,' AF="Kanselleer"' + ,'rsHelp:' + ,' EN="Help"' + ,' RU="Справка"' + ,' HU="Segítség"' + ,'rsOpen:' + ,' EN="Open"' + ,' RU="Открыть"' + ,' HU="Megnyitás"' + ,'rsSave:' + ,' EN="Save"' + ,' RU="Сохранить"' + ,' HU="Mentés"' + ,' AF="Stoor"' + ,'rsCreate:' + ,' EN="Create"' + ,' RU="Создать"' + ,' HU="Létrehoz"' + ,'rsChange:' + ,' EN="Change"' + ,' RU="Изменить"' + ,' HU="Változtat"' + ,' AF="Verander"' + ,'rsFind:' + ,' EN="Find"' + ,' RU="Найти"' + ,' HU="Talál"' + ,' AF="Vind"' + ,'rsSearch:' + ,' EN="Search"' + ,' RU="Поиск"' + ,' HU="Keres"' + ,' AF="Soek"' + ,'rsReplace:' + ,' EN="Replace"' + ,' RU="Заменить"' + ,' HU="Cserél"' + ,' AF="Vervang"' + ,'rsConfirm:' + ,' EN="Confirm"' + ,' RU="Подтвердить"' + ,' HU="Jóváhagy"' + ,'rsAll:' + ,' EN="All"' + ,' RU="Все"' + ,' HU="Mind"' + ,' AF="Alles"' + ,'rsSelect:' + ,' EN="Select"' + ,' RU="Выбрать"' + ,' HU="Kiválaszt"' + ,'rsYes:' + ,' EN="Yes"' + ,' RU="Да"' + ,' HU="Igen"' + ,' AF="Ja"' + ,'rsNo:' + ,' EN="No"' + ,' RU="Нет"' + ,' HU="Nem"' + ,' AF="Nee"' + ,'rsAbort:' + ,' EN="Abort"' + ,' RU="Прервать"' + ,' HU="Megszakít"' + ,'rsRetry:' + ,' EN="Retry"' + ,' RU="Повторить"' + ,' HU="Újra"' + ,'rsIgnore:' + ,' EN="Ignore"' + ,' RU="Пропустить"' + ,' HU="Kihagy"' + ,' AF="Ignoreer"' + ,'rsClose:' + ,' EN="Close"' + ,' RU="Закрыть"' + ,' HU="Bezár"' + ,' AF="Sluit"' + ,'rsInsert:' + ,' EN="Insert"' + ,' RU="Вставка"' + ,' HU="Beszúr"' + ,'rsEdit:' + ,' EN="Edit"' + ,' RU="Редактировать"' + ,' HU="Szerkeszt"' + ,'rsDelete:' + ,' EN="Delete"' + ,' RU="Удалить"' + ,' HU="Töröl"' + ,'rsExit:' + ,' EN="Exit"' + ,' RU="Выход"' + ,' HU="Kilép"' + ,' AF="Verlaat"' + ,'rsYesToAll:' + ,' EN="Yes to All"' + ,' RU="Да для всех"' + ,' HU="Mindre igen"' + ,'rsNoToAll:' + ,' EN="No to All"' + ,' RU="Нет для всех"' + ,' HU="Mindre nem"' + ,'rsCut:' + ,' EN="Cut"' + ,' RU="Вырезать"' + ,' HU="Kivág"' + ,'rsCopy:' + ,' EN="Copy"' + ,' RU="Копировать"' + ,' HU="Másol"' + ,'rsPaste:' + ,' EN="Paste"' + ,' RU="Вставить"' + ,' HU="Beilleszt"' + ,'rsError:' + ,' EN="Error"' + ,' HU="Hiba"' + ,'rsCriticalError:' + ,' EN="Critical Error"' + ,' HU="Kritikus hiba"' + ,'rsInformation:' + ,' EN="Information"' + ,' HU="Információ"' + ,'rsConfirmation:' + ,' EN="Confirmation"' + ,' HU="Megerősítés"' + ,'rsWarning:' + ,' EN="Warning"' + ,' HU="Figyelmeztetés"' + ,'rsMessage:' + ,' EN="Message"' + ,' HU="Üzenet"' + ,'rsAbout:' + ,' EN="About %s"' + ,' HU="About %s"' + ,'rsAllFiles:' + ,' EN="All Files"' + ,' HU="Összes fájl"' + ,'rsCreateDirectory:' + ,' EN="Create directory"' + ,' HU="Könyvtár létrehozása"' + ,'rsEnterNewDirectory:' + ,' EN="Enter new directory name"' + ,'rsCannotCreateDir:' + ,' EN="Cannot create directory"' + ,'rsSelectAFont:' + ,' EN="Select a font"' + ,'rsName:' + ,' EN="Name"' + ,' AF="Naam"' + ,'rsCollection:' + ,' EN="Collection"' + ,'rsSize:' + ,' EN="Size"' + ,' AF="Goote"' + ,'rsStyle:' + ,' EN="Style"' + ,' AF="Steil"' + ,'rsItalic:' + ,' EN="Italic"' + ,'rsBold:' + ,' EN="Bold"' + ,'rsUnderScore:' + ,' EN="UnderScore"' + ,'rsTypeface:' + ,' EN="Typeface"' + ,'rsAntiAliasing:' + ,' EN="Anti aliasing"' + ,'rsExampleText:' + ,' EN="Example Text"' + ,' AF="Voorbeeld Teks"' + ,'rsCollectionAllFonts:' + ,' EN="All Fonts"' + ,'rsCollectionRecentlyUsed:' + ,' EN="Recently Used"' + ,'rsCollectionFavourites:' + ,' EN="Favourites"' + ,'rsCollectionFixedWidth:' + ,' EN="Fixed Width"' + ,'rsCollectionSans:' + ,' EN="Sans"' + ,'rsCollectionSerif:' + ,' EN="Serif"' + ,'rsCollectionFontAliases:' + ,' EN="Font Aliases"' + ,'rsOpenAFile:' + ,' EN="Open a file"' + ,'rsFileName:' + ,' EN="Filename"' + ,'rsFileType:' + ,' EN="Type of file"' + ,'rsDrive:' + ,' EN="Drive"' + ,'rsFiles:' + ,' EN="Files"' + ,'rsDirectories:' + ,' EN="Directories"' + ,'rsShowHidden:' + ,' EN="Show hidden files"' + ,'rsFileSelection:' + ,' EN="File Selection"' + ,'rsFileModifiedTime:' + ,' EN="Mod. Time"' + ,'rsFileAttributes:' + ,' EN="Attributes"' + ,'rsFileRights:' + ,' EN="Rights"' + ,'rsFileOwner:' + ,' EN="Owner"' + ,'rsFileGroup:' + ,' EN="Group"' + ,'rsSaveAFile:' + ,' EN="Save file as"' + ,'rsErrListMustBeEmpty:' + ,' EN="List must be empty"' + ,'rsErrCouldNotOpenDir:' + ,' EN="Could not open the directory <%s>"' + ,'rsErrItemOfWrongType:' + ,' EN="Item is not of <%s> type!"' + ,'rsErrFailedToCreateDir:' + ,' EN="Failed to create the directory <%s>"' + ,'rsErrNotAssigned:' + ,' EN="<%s> not assigned"' + ,'rsShortMon:' + ,' EN="Mon"' + ,' HU="H"' + ,'rsShortTue:' + ,' EN="Tue"' + ,' HU="K"' + ,'rsShortWed:' + ,' EN="Wed"' + ,' HU="Sz"' + ,'rsShortThu:' + ,' EN="Thu"' + ,' HU="Cs"' + ,'rsShortFri:' + ,' EN="Fri"' + ,' HU="P"' + ,'rsShortSat:' + ,' EN="Sat"' + ,' HU="Szo"' + ,'rsShortSun:' + ,' EN="Sun"' + ,' HU="V"' + ,'rsLongMon:' + ,' EN="Monday"' + ,' HU="Hétfő"' + ,' AF="Maandag"' + ,'rsLongTue:' + ,' EN="Tuesday"' + ,' HU="Kedd"' + ,' AF="Dinsdag"' + ,'rsLongWed:' + ,' EN="Wednesday"' + ,' HU="Szerda"' + ,' AF="Woensdag"' + ,'rsLongThu:' + ,' EN="Thursday"' + ,' HU="Csütörtök"' + ,' AF="Donderdag"' + ,'rsLongFri:' + ,' EN="Friday"' + ,' HU="Péntek"' + ,' AF="Vrydag"' + ,'rsLongSat:' + ,' EN="Saturday"' + ,' HU="Szombat"' + ,' AF="Saterdag"' + ,'rsLongSun:' + ,' EN="Sunday"' + ,' HU="Vasárnap"' + ,' AF="Sondag"' + +); diff --git a/prototypes/miglayout/net/miginfocom/demo/CallbackDemo.java b/prototypes/miglayout/net/miginfocom/demo/CallbackDemo.java index 693271e4..2134582c 100644 --- a/prototypes/miglayout/net/miginfocom/demo/CallbackDemo.java +++ b/prototypes/miglayout/net/miginfocom/demo/CallbackDemo.java @@ -1,145 +1,145 @@ -package net.miginfocom.demo;
-
-import net.miginfocom.swing.MigLayout;
-import net.miginfocom.layout.*;
-import javax.swing.*;
-import java.awt.event.*;
-import java.awt.*;
-import java.util.IdentityHashMap;
-
-public class CallbackDemo extends JFrame implements ActionListener, MouseMotionListener, MouseListener
-{
- private final Timer repaintTimer = new Timer(20, new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- ((JPanel) getContentPane()).revalidate();
- }
- });
- private final IdentityHashMap<Object, Long> pressMap = new IdentityHashMap<Object, Long>();
- private Point mousePos = null;
-
- public CallbackDemo()
- {
- super("MiG Layout Callback Demo");
-
- MigLayout migLayout = new MigLayout("align center bottom, insets 30");
- final JPanel panel = new JPanel(migLayout) {
- protected void paintComponent(Graphics g)
- {
- ((Graphics2D) g).setPaint(new GradientPaint(0, getHeight() / 2, Color.WHITE, 0, getHeight(), new Color(240, 238, 235)));
- g.fillRect(0, 0, getWidth(), getHeight());
- }
- };
- setContentPane(panel);
-
- // This callback methods will be called for every layout cycle and let you make correction before and after the calculations.
- migLayout.addLayoutCallback(new LayoutCallback() {
-
- // This is the size change part
- public BoundSize[] getSize(ComponentWrapper comp)
- {
- if (comp.getComponent() instanceof JButton) {
- Component c = (Component) comp.getComponent();
- Point p = mousePos != null ? SwingUtilities.convertPoint(panel, mousePos, c) : new Point(-1000, -1000);
-
- float fact = (float) Math.sqrt(Math.pow(Math.abs(p.x - c.getWidth() / 2f), 2) + Math.pow(Math.abs(p.y - c.getHeight() / 2f), 2));
- fact = Math.max(2 - (fact / 200), 1);
-
- return new BoundSize[] {new BoundSize(new UnitValue(60 * fact), ""), new BoundSize(new UnitValue(60 * fact), "")};
- }
- return null;
- }
-
- // This is the jumping part
- public void correctBounds(ComponentWrapper c)
- {
- Long pressedNanos = pressMap.get(c.getComponent());
- if (pressedNanos != null) {
- long duration = System.nanoTime() - pressedNanos;
- double maxHeight = 100.0 - (duration / 100000000.0);
- int deltaY = (int) Math.round(Math.abs(Math.sin((duration) / 300000000.0) * maxHeight));
- c.setBounds(c.getX(), c.getY() - deltaY, c.getWidth(), c.getHeight());
-
- if (maxHeight < 0.5) {
- pressMap.remove(c.getComponent());
- if (pressMap.size() == 0)
- repaintTimer.stop();
- }
- }
- }
- });
-
- for (int j = 0; j < 10; j++)
- panel.add(createButton(j), "aligny 0.8al");
-
- JLabel label = new JLabel("Can't you just feel the urge to press one of those Swing JButtons?");
- label.setFont(new Font("verdana", Font.PLAIN, 24));
- label.setForeground(new Color(150, 150, 150));
- panel.add(label, "pos 0.5al 0.2al");
-
- panel.addMouseMotionListener(this);
- panel.addMouseListener(this);
- }
-
- private static Font[] FONTS = new Font[120];
- private JButton createButton(int i)
- {
- JButton button = new JButton(String.valueOf("MIG LAYOUT".charAt(i))) {
- public Font getFont()
- {
- if (FONTS[0] == null) {
- for (int i = 0; i < FONTS.length; i++)
- FONTS[i] = new Font("tahoma", Font.PLAIN, i);
- }
-
- return FONTS[getWidth() >> 1];
- }
- };
-
- button.setForeground(new Color(100, 100, 100));
- button.setFocusPainted(false);
- button.addMouseMotionListener(this);
- button.addActionListener(this);
- button.setMargin(new Insets(0, 0, 0, 0));
- return button;
- }
-
- public void mouseDragged(MouseEvent e) {}
- public void mouseMoved(MouseEvent e)
- {
- if (e.getSource() instanceof JButton) {
- mousePos = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), getContentPane());
- } else {
- mousePos = e.getPoint();
- }
- ((JPanel) getContentPane()).revalidate();
- }
-
- public void mousePressed(MouseEvent e) {}
- public void mouseReleased(MouseEvent e) {}
- public void mouseClicked(MouseEvent e) {}
- public void mouseEntered(MouseEvent e) {}
- public void mouseExited(MouseEvent e)
- {
- mousePos = null;
- ((JPanel) getContentPane()).revalidate();
- }
-
- public void actionPerformed(ActionEvent e)
- {
- pressMap.put(e.getSource(), System.nanoTime());
- repaintTimer.start();
- }
-
- public static void main(String args[])
- {
- try {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch (Exception ex) {}
-
- CallbackDemo demoFrame = new CallbackDemo();
- demoFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- demoFrame.setSize(970, 500);
- demoFrame.setLocationRelativeTo(null);
- demoFrame.setVisible(true);
- }
+package net.miginfocom.demo; + +import net.miginfocom.swing.MigLayout; +import net.miginfocom.layout.*; +import javax.swing.*; +import java.awt.event.*; +import java.awt.*; +import java.util.IdentityHashMap; + +public class CallbackDemo extends JFrame implements ActionListener, MouseMotionListener, MouseListener +{ + private final Timer repaintTimer = new Timer(20, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ((JPanel) getContentPane()).revalidate(); + } + }); + private final IdentityHashMap<Object, Long> pressMap = new IdentityHashMap<Object, Long>(); + private Point mousePos = null; + + public CallbackDemo() + { + super("MiG Layout Callback Demo"); + + MigLayout migLayout = new MigLayout("align center bottom, insets 30"); + final JPanel panel = new JPanel(migLayout) { + protected void paintComponent(Graphics g) + { + ((Graphics2D) g).setPaint(new GradientPaint(0, getHeight() / 2, Color.WHITE, 0, getHeight(), new Color(240, 238, 235))); + g.fillRect(0, 0, getWidth(), getHeight()); + } + }; + setContentPane(panel); + + // This callback methods will be called for every layout cycle and let you make correction before and after the calculations. + migLayout.addLayoutCallback(new LayoutCallback() { + + // This is the size change part + public BoundSize[] getSize(ComponentWrapper comp) + { + if (comp.getComponent() instanceof JButton) { + Component c = (Component) comp.getComponent(); + Point p = mousePos != null ? SwingUtilities.convertPoint(panel, mousePos, c) : new Point(-1000, -1000); + + float fact = (float) Math.sqrt(Math.pow(Math.abs(p.x - c.getWidth() / 2f), 2) + Math.pow(Math.abs(p.y - c.getHeight() / 2f), 2)); + fact = Math.max(2 - (fact / 200), 1); + + return new BoundSize[] {new BoundSize(new UnitValue(60 * fact), ""), new BoundSize(new UnitValue(60 * fact), "")}; + } + return null; + } + + // This is the jumping part + public void correctBounds(ComponentWrapper c) + { + Long pressedNanos = pressMap.get(c.getComponent()); + if (pressedNanos != null) { + long duration = System.nanoTime() - pressedNanos; + double maxHeight = 100.0 - (duration / 100000000.0); + int deltaY = (int) Math.round(Math.abs(Math.sin((duration) / 300000000.0) * maxHeight)); + c.setBounds(c.getX(), c.getY() - deltaY, c.getWidth(), c.getHeight()); + + if (maxHeight < 0.5) { + pressMap.remove(c.getComponent()); + if (pressMap.size() == 0) + repaintTimer.stop(); + } + } + } + }); + + for (int j = 0; j < 10; j++) + panel.add(createButton(j), "aligny 0.8al"); + + JLabel label = new JLabel("Can't you just feel the urge to press one of those Swing JButtons?"); + label.setFont(new Font("verdana", Font.PLAIN, 24)); + label.setForeground(new Color(150, 150, 150)); + panel.add(label, "pos 0.5al 0.2al"); + + panel.addMouseMotionListener(this); + panel.addMouseListener(this); + } + + private static Font[] FONTS = new Font[120]; + private JButton createButton(int i) + { + JButton button = new JButton(String.valueOf("MIG LAYOUT".charAt(i))) { + public Font getFont() + { + if (FONTS[0] == null) { + for (int i = 0; i < FONTS.length; i++) + FONTS[i] = new Font("tahoma", Font.PLAIN, i); + } + + return FONTS[getWidth() >> 1]; + } + }; + + button.setForeground(new Color(100, 100, 100)); + button.setFocusPainted(false); + button.addMouseMotionListener(this); + button.addActionListener(this); + button.setMargin(new Insets(0, 0, 0, 0)); + return button; + } + + public void mouseDragged(MouseEvent e) {} + public void mouseMoved(MouseEvent e) + { + if (e.getSource() instanceof JButton) { + mousePos = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), getContentPane()); + } else { + mousePos = e.getPoint(); + } + ((JPanel) getContentPane()).revalidate(); + } + + public void mousePressed(MouseEvent e) {} + public void mouseReleased(MouseEvent e) {} + public void mouseClicked(MouseEvent e) {} + public void mouseEntered(MouseEvent e) {} + public void mouseExited(MouseEvent e) + { + mousePos = null; + ((JPanel) getContentPane()).revalidate(); + } + + public void actionPerformed(ActionEvent e) + { + pressMap.put(e.getSource(), System.nanoTime()); + repaintTimer.start(); + } + + public static void main(String args[]) + { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception ex) {} + + CallbackDemo demoFrame = new CallbackDemo(); + demoFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + demoFrame.setSize(970, 500); + demoFrame.setLocationRelativeTo(null); + demoFrame.setVisible(true); + } }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/demo/SwingDemo.java b/prototypes/miglayout/net/miginfocom/demo/SwingDemo.java index 42f9b13c..ddc45a38 100644 --- a/prototypes/miglayout/net/miginfocom/demo/SwingDemo.java +++ b/prototypes/miglayout/net/miginfocom/demo/SwingDemo.java @@ -1,3668 +1,3668 @@ -package net.miginfocom.demo;
-
-import net.miginfocom.layout.*;
-import net.miginfocom.swing.MigLayout;
-
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import javax.swing.border.EtchedBorder;
-import javax.swing.border.LineBorder;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import java.awt.*;
-import java.awt.event.*;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Random;
-
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-public class SwingDemo extends JFrame
-{
- public static final int INITIAL_INDEX = 0;
- private static final boolean DEBUG = false;
- private static final boolean OPAQUE = false;
-
- private static final String[][] panels = new String[][] {
-// {"Test", "Test, disregard"},
- {"Welcome", "\n\n \"MigLayout makes complex layouts easy and normal layouts one-liners.\""},
- {"Quick Start", "This is an example of how to build a common dialog type. Note that there are no special components, nested panels or absolute references to cell positions. If you look at the source code you will see that the layout code is very simple to understand."},
- {"Plain", "A simple example on how simple it is to create normal forms. No builders needed since the whole layout manager works like a builder."},
- {"Alignments", "Shows how the alignment of components are specified. At the top/left is the alignment for the column/row. The components have no alignments specified.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."},
- {"Cell Alignments", "Shows how components are aligned when both column/row alignments and component constraints are specified. At the top/left are the alignment for the column/row and the text on the buttons is the component constraint that will override the column/row alignment if it is an alignment.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."},
- {"Basic Sizes", "A simple example that shows how to use the column or row min/preferred/max size to set the sizes of the contained components and also an example that shows how to do this directly in the component constraints."},
- {"Growing", "A simple example that shows how to use the growx and growy constraint to set the sizes and how they should grow to fit the available size. Both the column/row and the component grow/shrink constraints can be set, but the components will always be confined to the space given by its column/row."},
- {"Grow Shrink", "Demonstrates the very flexible grow and shrink constraints that can be set on a component.\nComponents can be divided into grow/shrink groups and also have grow/shrink weight within each of those groups.\n\nBy default " +
- "components shrink to their inherent (or specified) minimum size, but they don't grow."},
- {"Span", "This example shows the powerful spanning and splitting that can be specified in the component constraints. With spanning any number of cells can be merged with the additional option to split that space for more than one component. This makes layouts very flexible and reduces the number of times you will need nested panels to very few."},
- {"Flow Direction", "Shows the different flow directions. Flow direction for the layout specifies if the next cell will be in the x or y dimension. Note that it can be a different flow direction in the slit cell (the middle cell is slit in two). Wrap is set to 3 for all panels."},
- {"Grouping", "Sizes for both components and columns/rows can be grouped so they get the same size. For instance buttons in a button bar can be given a size-group so that they will all get " +
- "the same minimum and preferred size (the largest within the group). Size-groups can be set for the width, height or both."},
- {"Units", "Demonstrates the basic units that are understood by MigLayout. These units can be extended by the user by adding one or more UnitConverter(s)."},
- {"Component Sizes", "Minimum, preferred and maximum component sizes can be overridden in the component constraints using any unit type. The format to do this is short and simple to understand. You simply specify the " +
- "min, preferred and max sizes with a colon between.\n\nAbove are some examples of this. An exclamation mark means that the value will be used for all sizes."},
- {"Bound Sizes", "Shows how to create columns that are stable between tabs using minimum sizes."},
- {"Cell Position", "Even though MigLayout has automatic grid flow you can still specify the cell position explicitly. You can even combine absolute (x, y) and flow (skip, wrap and newline) constraints to build your layout."},
- {"Orientation", "MigLayout supports not only right-to-left orientation, but also bottom-to-top. You can even set the flow direction so that the flow is vertical instead of horizontal. It will automatically " +
- "pick up if right-to-left is to be used depending on the ComponentWrapper, but it can also be manually set for every layout."},
- {"Absolute Position", "Demonstrates the option to place any number of components using absolute coordinates. This can be just the position (if min/preferred size) using \"x y p p\" format or" +
- "the bounds using the \"x1 y1 x2 y2\" format. Any unit can be used and percent is relative to the parent.\nAbsolute components will not disturb the flow or occupy cells in the grid. " +
- "Absolute positioned components will be taken into account when calculating the container's preferred size."},
- {"Component Links", "Components can be linked to any side of any other component. It can be a forward, backward or cyclic link references, as long as it is stable and won't continue to change value over many iterations." +
- "Links are referencing the ID of another component. The ID can be overridden by the component's constrains or is provided by the ComponentWrapper. For instance it will use the component's 'name' on Swing.\n" +
- "Since the links can be combined with any expression (such as 'butt1.x+10' or 'max(button.x, 200)' the links are very customizable."},
- {"Docking", "Docking components can be added around the grid. The docked component will get the whole width/height on the docked side by default, however this can be overridden. When all docked components are laid out, whatever space " +
- "is left will be available for the normal grid laid out components. Docked components does not in any way affect the flow in the grid.\n\nSince the docking runs in the same code path " +
- "as the normal layout code the same properties can be specified for the docking components. You can for instance set the sizes and alignment or link other components to their docked component's bounds."},
- {"Button Bars", "Button order is very customizable and are by default different on the supported platforms. E.g. Gaps, button order and minimum button size are properties that are 'per platform'. MigLayout picks up the current platform automatically and adjusts the button order and minimum button size accordingly, all without using a button builder or any other special code construct."},
- {"Visual Bounds", "Human perceptible bounds may not be the same as the mathematical bounds for the component. This is for instance the case if there is a drop shadow painted by the component's border. MigLayout can compensate " +
- "for this in a simple way. Note the top middle tab-component, it is not aligned visually correct on Windows XP. For the second tab the bounds are corrected automatically on Windows XP."},
- {"Debug", "Demonstrates the non-intrusive way to get visual debugging aid. There is no need to use a special DebugPanel or anything that will need code changes. The user can simply turn on debug on the layout manager by using the \"debug\" constraint and it will " +
- "continuously repaint the panel with debug information on top. This means you don't have to change your code to debug!"},
- {"Layout Showdown", "This is an implementation of the Layout Showdown posted on java.net by John O'Conner. The first tab is a pure implemenetation of the showdown that follows all the rules. The second tab is a slightly fixed version that follows some improved layout guidelines." +
- "The source code is for bothe the first and for the fixed version. Note the simplification of the code for the fixed version. Writing better layouts with MiG Layout is reasier that writing bad.\n\nReference: http://weblogs.java.net/blog/joconner/archive/2006/10/more_informatio.html"},
- {"API Constraints1", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."},
- {"API Constraints2", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."}
- };
-
- private int lastIndex = -10;
-
- private JPanel contentPanel = DEBUG ? new JPanel(new BorderLayout()) : new JPanel(new MigLayout("wrap", "[]unrel[grow]", "[grow][pref]"));
-
- private JTabbedPane layoutPickerTabPane = new JTabbedPane();
- private JList pickerList = new JList(new DefaultListModel());
-
- private JTabbedPane southTabPane = new JTabbedPane();
- private JScrollPane descrTextAreaScroll = createTextAreaScroll("", 5, 80, true);
- private JTextArea descrTextArea = (JTextArea) descrTextAreaScroll.getViewport().getView();
-
- private JScrollPane sourceTextAreaScroll = null;
- private JTextArea sourceTextArea = null;
-
- private JPanel layoutDisplayPanel = new JPanel(new BorderLayout(0, 0));
- private static boolean buttonOpaque = true;
- private JFrame sourceFrame = null;
- private JTextArea sourceFrameTextArea = null;
-
- private static int benchRuns = 0;
- private static long startupMillis = 0;
- private static long timeToShowMillis = 0;
- private static long benchRunTime = 0;
- private static String benchOutFileName = null;
- private static boolean append = false;
- private static long lastRunTimeStart = 0;
- private static StringBuffer runTimeSB = null;
-
- public static void main(String args[])
- {
- try {
- System.setProperty("apple.laf.useScreenMenuBar", "true");
- System.setProperty("com.apple.mrj.application.apple.menu.about.name", "MiGLayout Swing Demo");
- } catch(Throwable ex) {
- // Beacuse we did not have permissions.
- }
-
- startupMillis = System.currentTimeMillis();
-
- String laf = UIManager.getSystemLookAndFeelClassName();
-
- if (args.length > 0) {
- for (int i = 0; i <args.length; i++) {
- String arg = args[i].trim();
- if (arg.startsWith("-laf")) {
- laf = arg.substring(4);
- } else if (arg.startsWith("-bench")) {
- benchRuns = 10;
- try {
- benchRuns = Integer.parseInt(arg.substring(6));
- } catch(Exception ex) {}
- } else if (arg.startsWith("-bout")) {
- benchOutFileName = arg.substring(5);
- } else if (arg.startsWith("-append")) {
- append = true;
- } else if (arg.startsWith("-verbose")) {
- runTimeSB = new StringBuffer(256);
- } else if (arg.equals("-steel")) {
- laf = "javax.swing.plaf.metal.MetalLookAndFeel";
- System.setProperty("swing.metalTheme", "steel");
- } else if (arg.equals("-ocean")) {
- laf = "javax.swing.plaf.metal.MetalLookAndFeel";
- } else {
- System.out.println("Usage: [-laf[look_&_feel_class_name]] [-bench[#_of_runs]] [-bout[benchmark_results_filename]] [-append] [-steel] [-ocean]\n" +
- " -laf Set the Application Look&Feel. (Look and feel must be in Classpath)\n" +
- " -bench Run demo as benchmark. Run count can be appended. 10 is default.\n" +
- " -bout Benchmark results output filename.\n" +
- " -append Appends the result to the -bout file.\n" +
- " -verbose Print the times of every run.\n" +
- " -steel Sets the old Steel theme for Sun's Metal look&feel.\n" +
- " -ocean Sets the Ocean theme for Sun's Metal look&feel.\n" +
- "\nExamples:\n" +
- " java -jar swingdemoapp.jar -bench -boutC:/bench.txt -append\n" +
- " java -jar swingdemoapp.jar -ocean -bench20\n" +
- " java -cp c:\\looks-2.0.4.jar;.\\swingdemoapp.jar net.miginfocom.demo.SwingDemo -lafcom.jgoodies.looks.plastic.PlasticLookAndFeel -bench20 -boutC:/bench.txt");
- System.exit(0);
- }
- }
- }
-
- if (benchRuns > 0)
- LayoutUtil.setDesignTime(null, true); // So that the string constraints to create the UnitValues is saved and can be recreated exactly.
-
-// laf = "net.sourceforge.napkinlaf.NapkinLookAndFeel";
-// laf = "javax.swing.plaf.metal.MetalLookAndFeel";
-// System.setProperty("swing.metalTheme", "steel");
-// laf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
-// laf = "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel";
-// laf = "com.jgoodies.looks.plastic.PlasticLookAndFeel";
-// laf = "com.jgoodies.looks.plastic.Plastic3DLookAndFeel";
-// laf = "com.jgoodies.looks.plastic.PlasticXPLookAndFeel";
-// laf = "com.jgoodies.looks.windows.WindowsLookAndFeel";
-
- if (laf.endsWith("WindowsLookAndFeel"))
- buttonOpaque = false;
-
- final String laff = laf;
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- try {
- UIManager.setLookAndFeel(laff);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
-
- SwingDemo demo = new SwingDemo();
- }
- });
- }
-
- public SwingDemo()
- {
- super("MigLayout Swing Demo v2.4 - Mig Layout v" + LayoutUtil.getVersion());
-
-// if (benchRuns > 0)
-// RepaintManager.currentManager(this).setDoubleBufferingEnabled(false);
-
- if (benchRuns == 0) {
- sourceTextAreaScroll = createTextAreaScroll("", 5, 80, true);
- sourceTextArea = (JTextArea) sourceTextAreaScroll.getViewport().getView();
- }
-
- if (DEBUG) {
- contentPanel.add(layoutDisplayPanel, BorderLayout.CENTER);
-// contentPanel.add(layoutPickerTabPane, BorderLayout.WEST);
-// contentPanel.add(descriptionTabPane, BorderLayout.SOUTH);
- } else {
- contentPanel.add(layoutPickerTabPane, "spany,grow");
- contentPanel.add(layoutDisplayPanel, "grow");
- contentPanel.add(southTabPane, "growx");
- }
-
- setContentPane(contentPanel);
-
- pickerList.setOpaque(OPAQUE);
- ((DefaultListCellRenderer) pickerList.getCellRenderer()).setOpaque(OPAQUE);
- pickerList.setSelectionForeground(new Color(0, 0, 220));
- pickerList.setBackground(null);
- pickerList.setBorder(new EmptyBorder(2, 5, 0, 4));
- pickerList.setFont(pickerList.getFont().deriveFont(Font.BOLD));
- layoutPickerTabPane.addTab("Example Browser", pickerList);
-
- descrTextAreaScroll.setBorder(null);
- descrTextAreaScroll.setOpaque(OPAQUE);
- descrTextAreaScroll.getViewport().setOpaque(OPAQUE);
- descrTextArea.setOpaque(OPAQUE);
- descrTextArea.setEditable(false);
- descrTextArea.setBorder(new EmptyBorder(0, 4, 0, 4));
- southTabPane.addTab("Description", descrTextAreaScroll);
-
-
- if (sourceTextArea != null) {
- sourceTextAreaScroll.setBorder(null);
- sourceTextAreaScroll.setOpaque(OPAQUE);
- sourceTextAreaScroll.getViewport().setOpaque(OPAQUE);
- sourceTextAreaScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- sourceTextArea.setOpaque(OPAQUE);
- sourceTextArea.setLineWrap(false);
- sourceTextArea.setWrapStyleWord(false);
- sourceTextArea.setEditable(false);
- sourceTextArea.setBorder(new EmptyBorder(0, 4, 0, 4));
- sourceTextArea.setFont(new Font("monospaced", Font.PLAIN, 11));
- southTabPane.addTab("Source Code", sourceTextAreaScroll);
-
- southTabPane.addMouseListener(new MouseAdapter() {
- public void mouseClicked(MouseEvent e)
- {
- if (e.getClickCount() == 2)
- showSourceInFrame();
- }
- });
- }
-
- for (int i = 0; i < panels.length; i++)
- ((DefaultListModel) pickerList.getModel()).addElement(panels[i][0]);
-
- try {
- setSize(900, 650);
- setLocationRelativeTo(null);
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- setVisible(true);
- } catch(Throwable t) {
- t.printStackTrace();
- System.exit(1);
- }
-
- pickerList.addListSelectionListener(new ListSelectionListener() {
- public void valueChanged(ListSelectionEvent e)
- {
- int ix = pickerList.getSelectedIndex();
- if (ix == -1 || lastIndex == ix)
- return;
-
- lastIndex = ix;
-
- String methodName = "create" + panels[ix][0].replace(' ', '_');
- layoutDisplayPanel.removeAll();
- try {
- pickerList.requestFocusInWindow();
- final JComponent panel = (JComponent) SwingDemo.class.getMethod(methodName, new Class[0]).invoke(SwingDemo.this, new Object[0]);
- layoutDisplayPanel.add(panel);
- descrTextArea.setText(panels[ix][1]);
- descrTextArea.setCaretPosition(0);
- contentPanel.revalidate();
-
- } catch (Exception e1) {
- e1.printStackTrace(); // Should never happpen...
- }
- southTabPane.setSelectedIndex(0);
- }
- });
-
- pickerList.requestFocusInWindow();
- Toolkit.getDefaultToolkit().setDynamicLayout(true);
-
- if (benchRuns > 0) {
- doBenchmark();
- } else {
- pickerList.setSelectedIndex(INITIAL_INDEX);
-
- KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
- public boolean dispatchKeyEvent(KeyEvent e)
- {
- if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_B && (e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) > 0) {
- startupMillis = System.currentTimeMillis();
- timeToShowMillis = System.currentTimeMillis() - startupMillis;
- benchRuns = 1;
- doBenchmark();
- return true;
- }
- return false;
- }
- });
- }
- }
-
- private void doBenchmark()
- {
- Thread benchThread = new Thread() {
- public void run()
- {
- for (int j = 0; j < benchRuns; j++) {
- lastRunTimeStart = System.currentTimeMillis();
- for (int i = 0, iCnt = pickerList.getModel().getSize(); i < iCnt; i++) {
-
- if (benchRuns > 0 && panels[i][0].equals("Visual Bounds"))
- continue; // the SWT version does not have Visual bounds...
-
- final int ii = i;
- try {
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- pickerList.setSelectedIndex(ii);
- Toolkit.getDefaultToolkit().sync();
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- Component[] comps = layoutDisplayPanel.getComponents();
- for (int cIx = 0; cIx < comps.length; cIx++) {
- if (comps[cIx] instanceof JTabbedPane) {
- final JTabbedPane tp = (JTabbedPane) comps[cIx];
-
- for (int k = 0, kCnt = tp.getTabCount(); k < kCnt; k++) {
- final int kk = k;
- try {
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- tp.setSelectedIndex(kk);
- Toolkit.getDefaultToolkit().sync();
-
- if (timeToShowMillis == 0)
- timeToShowMillis = System.currentTimeMillis() - startupMillis;
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
- if (runTimeSB != null) {
- runTimeSB.append("Run ").append(j).append(": ");
- runTimeSB.append(System.currentTimeMillis() - lastRunTimeStart).append(" millis.\n");
- }
- }
-
- benchRunTime = System.currentTimeMillis() - startupMillis - timeToShowMillis;
-
- final String message = "Java Version: " + System.getProperty("java.version") + "\n" +
- "Look & Feel: " + UIManager.getLookAndFeel().getDescription() + "\n" +
- "Time to Show: " + timeToShowMillis + " millis.\n" +
- (runTimeSB != null ? runTimeSB.toString() : "") +
- "Benchmark Run Time: " + benchRunTime + " millis.\n" +
- "Average Run Time: " + (benchRunTime / benchRuns) + " millis (" + benchRuns + " runs).\n\n";
-
- if (benchOutFileName == null) {
- JOptionPane.showMessageDialog(SwingDemo.this, message, "Results", JOptionPane.INFORMATION_MESSAGE);
- } else {
- FileWriter fw = null;
- try {
- fw = new FileWriter(benchOutFileName, append);
- fw.write(message);
- } catch(IOException ex) {
- ex.printStackTrace();
- } finally {
- if (fw != null)
- try {fw.close();} catch(IOException ex) {}
- }
- }
- System.out.println(message);
- }
- };
- benchThread.start();
- }
-
- private void setSource(String source)
- {
- if (benchRuns > 0 || sourceTextArea == null)
- return;
-
- if (source.length() > 0) {
- source = source.replaceAll("\t\t", "");
- source = "DOUBLE CLICK TAB TO SHOW SOURCE IN SEPARATE WINDOW!\n===================================================\n\n" + source;
- }
- sourceTextArea.setText(source);
- sourceTextArea.setCaretPosition(0);
-
- if (sourceFrame != null && sourceFrame.isVisible()) {
- sourceFrameTextArea.setText(source.length() > 105 ? source.substring(105) : "No Source Code Available!");
- sourceFrameTextArea.setCaretPosition(0);
- }
- }
-
- private void showSourceInFrame()
- {
- if (sourceTextArea == null)
- return;
-
- JScrollPane sourceFrameTextAreaScroll = createTextAreaScroll("", 5, 80, true);
- sourceFrameTextArea = (JTextArea) sourceFrameTextAreaScroll.getViewport().getView();
-
- sourceFrameTextAreaScroll.setBorder(null);
- sourceFrameTextAreaScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- sourceFrameTextArea.setLineWrap(false);
- sourceFrameTextArea.setWrapStyleWord(false);
- sourceFrameTextArea.setEditable(false);
- sourceFrameTextArea.setBorder(new EmptyBorder(10, 10, 10, 10));
- sourceFrameTextArea.setFont(new Font("monospaced", Font.PLAIN, 12));
-
- String source = this.sourceTextArea.getText();
- sourceFrameTextArea.setText(source.length() > 105 ? source.substring(105) : "No Source Code Available!");
- sourceFrameTextArea.setCaretPosition(0);
-
- sourceFrame = new JFrame("Source Code");
- sourceFrame.getContentPane().add(sourceFrameTextAreaScroll, BorderLayout.CENTER);
- sourceFrame.setSize(700, 800);
- sourceFrame.setLocationRelativeTo(this);
- sourceFrame.setVisible(true);
- }
-
- public JComponent createTest()
- {
- JComponent pane = new JPanel();
-
- pane.setLayout(new MigLayout("debug"));
-
- pane.add(new JLabel("Separator"), "gapbottom 1, ax r, spanx, split");
- pane.add(new JSeparator(), "gap rel, growx");
-
- JLabel label = new JLabel("<html><font color=red><b>some text in label</b></font></html>");
-
-
- pane.add(label, "wrap");
- pane.add(new JButton("Button1"));
- pane.add(new JButton("Button2"));
- pane.add(new JButton("Button3"));
-
- return pane;
- }
-
- public JComponent createAPI_Constraints1()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- LC layC = new LC().fill().wrap();
- AC colC = new AC().align("right", 1).fill(2, 4).grow(100, 2, 4).align("right", 3).gap("15", 2);
- AC rowC = new AC().align("top", 7).gap("15!", 6).grow(100, 8);
-
- JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient
-
- // References to text fields not stored to reduce code clutter.
-
- JScrollPane list2 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"}));
- panel.add(list2, new CC().spanY().growY().minWidth("150").gapX(null, "10"));
-
- panel.add(new JLabel("Last Name"));
- panel.add(new JTextField());
- panel.add(new JLabel("First Name"));
- panel.add(new JTextField(), new CC().wrap().alignX("right"));
- panel.add(new JLabel("Phone"));
- panel.add(new JTextField());
- panel.add(new JLabel("Email"));
- panel.add(new JTextField());
- panel.add(new JLabel("Address 1"));
- panel.add(new JTextField(), new CC().spanX().growX());
- panel.add(new JLabel("Address 2"));
- panel.add(new JTextField(), new CC().spanX().growX());
- panel.add(new JLabel("City"));
- panel.add(new JTextField(), new CC().wrap());
- panel.add(new JLabel("State"));
- panel.add(new JTextField());
- panel.add(new JLabel("Postal Code"));
- panel.add(new JTextField(10), new CC().spanX(2).growX(0));
- panel.add(new JLabel("Country"));
- panel.add(new JTextField(), new CC().wrap());
-
- panel.add(new JButton("New"), new CC().spanX(5).split(5).tag("other"));
- panel.add(new JButton("Delete"), new CC().tag("other"));
- panel.add(new JButton("Edit"), new CC().tag("other"));
- panel.add(new JButton("Save"), new CC().tag("other"));
- panel.add(new JButton("Cancel"), new CC().tag("cancel"));
-
- tabbedPane.addTab("Layout Showdown (improved)", panel);
-
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "LC layC = new LC().fill().wrap();\n" +
- "AC colC = new AC().align(\"right\", 1).fill(2, 4).grow(100, 2, 4).align(\"right\", 3).gap(\"15\", 2);\n" +
- "AC rowC = new AC().align(\"top\", 7).gap(\"15!\", 6).grow(100, 8);\n" +
- "\n" +
- "JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient\n" +
- "\n" +
- "// References to text fields not stored to reduce code clutter.\n" +
- "\n" +
- "JScrollPane list2 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" +
- "panel.add(list2, new CC().spanY().growY().minWidth(\"150\").gapX(null, \"10\"));\n" +
- "\n" +
- "panel.add(new JLabel(\"Last Name\"));\n" +
- "panel.add(new JTextField());\n" +
- "panel.add(new JLabel(\"First Name\"));\n" +
- "panel.add(new JTextField(), new CC().wrap().alignX(\"right\"));\n" +
- "panel.add(new JLabel(\"Phone\"));\n" +
- "panel.add(new JTextField());\n" +
- "panel.add(new JLabel(\"Email\"));\n" +
- "panel.add(new JTextField());\n" +
- "panel.add(new JLabel(\"Address 1\"));\n" +
- "panel.add(new JTextField(), new CC().spanX().growX());\n" +
- "panel.add(new JLabel(\"Address 2\"));\n" +
- "panel.add(new JTextField(), new CC().spanX().growX());\n" +
- "panel.add(new JLabel(\"City\"));\n" +
- "panel.add(new JTextField(), new CC().wrap());\n" +
- "panel.add(new JLabel(\"State\"));\n" +
- "panel.add(new JTextField());\n" +
- "panel.add(new JLabel(\"Postal Code\"));\n" +
- "panel.add(new JTextField(10), new CC().spanX(2).growX(0));\n" +
- "panel.add(new JLabel(\"Country\"));\n" +
- "panel.add(new JTextField(), new CC().wrap());\n" +
- "\n" +
- "panel.add(new JButton(\"New\"), new CC().spanX(5).split(5).tag(\"other\"));\n" +
- "panel.add(new JButton(\"Delete\"), new CC().tag(\"other\"));\n" +
- "panel.add(new JButton(\"Edit\"), new CC().tag(\"other\"));\n" +
- "panel.add(new JButton(\"Save\"), new CC().tag(\"other\"));\n" +
- "panel.add(new JButton(\"Cancel\"), new CC().tag(\"cancel\"));\n" +
- "\n" +
- "tabbedPane.addTab(\"Layout Showdown (improved)\", panel);");
-
- return tabbedPane;
- }
-
- public JComponent createAPI_Constraints2()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- LC layC = new LC().fill().wrap();
- AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1);
- AC rowC = new AC().index(6).gap("15!").align("top").grow(100, 8);
-
- JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient
-
- // References to text fields not stored to reduce code clutter.
-
- panel.add(new JLabel("Last Name"));
- panel.add(new JTextField());
- panel.add(new JLabel("First Name"));
- panel.add(new JTextField(), new CC().wrap());
- panel.add(new JLabel("Phone"));
- panel.add(new JTextField());
- panel.add(new JLabel("Email"));
- panel.add(new JTextField());
- panel.add(new JLabel("Address 1"));
- panel.add(new JTextField(), new CC().spanX().growX());
- panel.add(new JLabel("Address 2"));
- panel.add(new JTextField(), new CC().spanX().growX());
- panel.add(new JLabel("City"));
- panel.add(new JTextField(), new CC().wrap());
- panel.add(new JLabel("State"));
- panel.add(new JTextField());
- panel.add(new JLabel("Postal Code"));
- panel.add(new JTextField(10), new CC().spanX(2).growX(0));
- panel.add(new JLabel("Country"));
- panel.add(new JTextField(), new CC().wrap());
-
- panel.add(createButton("New"), new CC().spanX(5).split(5).tag("other"));
- panel.add(createButton("Delete"), new CC().tag("other"));
- panel.add(createButton("Edit"), new CC().tag("other"));
- panel.add(createButton("Save"), new CC().tag("other"));
- panel.add(createButton("Cancel"), new CC().tag("cancel"));
-
- tabbedPane.addTab("Layout Showdown (improved)", panel);
-
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "LC layC = new LC().fill().wrap();\n" +
- "AC colC = new AC().align(\"right\", 0).fill(1, 3).grow(100, 1, 3).align(\"right\", 2).gap(\"15\", 1);\n" +
- "AC rowC = new AC().index(6).gap(\"15!\").align(\"top\").grow(100, 8);\n" +
- "\n" +
- "JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient\n" +
- "\n" +
- "// References to text fields not stored to reduce code clutter.\n" +
- "\n" +
- "panel.add(new JLabel(\"Last Name\"));\n" +
- "panel.add(new JTextField());\n" +
- "panel.add(new JLabel(\"First Name\"));\n" +
- "panel.add(new JTextField(), new CC().wrap());\n" +
- "panel.add(new JLabel(\"Phone\"));\n" +
- "panel.add(new JTextField());\n" +
- "panel.add(new JLabel(\"Email\"));\n" +
- "panel.add(new JTextField());\n" +
- "panel.add(new JLabel(\"Address 1\"));\n" +
- "panel.add(new JTextField(), new CC().spanX().growX());\n" +
- "panel.add(new JLabel(\"Address 2\"));\n" +
- "panel.add(new JTextField(), new CC().spanX().growX());\n" +
- "panel.add(new JLabel(\"City\"));\n" +
- "panel.add(new JTextField(), new CC().wrap());\n" +
- "panel.add(new JLabel(\"State\"));\n" +
- "panel.add(new JTextField());\n" +
- "panel.add(new JLabel(\"Postal Code\"));\n" +
- "panel.add(new JTextField(10), new CC().spanX(2).growX(0));\n" +
- "panel.add(new JLabel(\"Country\"));\n" +
- "panel.add(new JTextField(), new CC().wrap());\n" +
- "\n" +
- "panel.add(createButton(\"New\"), new CC().spanX(5).split(5).tag(\"other\"));\n" +
- "panel.add(createButton(\"Delete\"), new CC().tag(\"other\"));\n" +
- "panel.add(createButton(\"Edit\"), new CC().tag(\"other\"));\n" +
- "panel.add(createButton(\"Save\"), new CC().tag(\"other\"));\n" +
- "panel.add(createButton(\"Cancel\"), new CC().tag(\"cancel\"));\n" +
- "\n" +
- "tabbedPane.addTab(\"Layout Showdown (improved)\", panel);");
-
- return tabbedPane;
- }
-
- public JComponent createLayout_Showdown()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- JPanel p = createTabPanel(new MigLayout("", "[]15[][grow,fill]15[grow]"));
-
- JScrollPane list1 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"}));
-
- p.add(list1, "spany, growy, wmin 150");
- p.add(new JLabel("Last Name"));
- p.add(new JTextField());
- p.add(new JLabel("First Name"), "split"); // split divides the cell
- p.add(new JTextField(), "growx, wrap");
- p.add(new JLabel("Phone"));
- p.add(new JTextField());
- p.add(new JLabel("Email"), "split");
- p.add(new JTextField(), "growx, wrap");
- p.add(new JLabel("Address 1"));
- p.add(new JTextField(), "span, growx"); // span merges cells
- p.add(new JLabel("Address 2"));
- p.add(new JTextField(), "span, growx");
- p.add(new JLabel("City"));
- p.add(new JTextField(), "wrap"); // wrap continues on next line
- p.add(new JLabel("State"));
- p.add(new JTextField());
- p.add(new JLabel("Postal Code"), "split");
- p.add(new JTextField(), "growx, wrap");
- p.add(new JLabel("Country"));
- p.add(new JTextField(), "wrap 15");
-
- p.add(createButton("New"), "span, split, align left");
- p.add(createButton("Delete"), "");
- p.add(createButton("Edit"), "");
- p.add(createButton("Save"), "");
- p.add(createButton("Cancel"), "wrap push");
-
- tabbedPane.addTab("Layout Showdown (pure)", p);
-
-
- // Fixed version *******************************************
-
- JPanel p2 = createTabPanel(new MigLayout("", "[]15[][grow,fill]15[][grow,fill]")); // Makes the background gradient
-
- // References to text fields not stored to reduce code clutter.
-
- JScrollPane list2 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"}));
- p2.add(list2, "spany, growy, wmin 150");
- p2.add(new JLabel("Last Name"));
- p2.add(new JTextField());
- p2.add(new JLabel("First Name"));
- p2.add(new JTextField(), "wrap");
- p2.add(new JLabel("Phone"));
- p2.add(new JTextField());
- p2.add(new JLabel("Email"));
- p2.add(new JTextField(), "wrap");
- p2.add(new JLabel("Address 1"));
- p2.add(new JTextField(), "span");
- p2.add(new JLabel("Address 2"));
- p2.add(new JTextField(), "span");
- p2.add(new JLabel("City"));
- p2.add(new JTextField(), "wrap");
- p2.add(new JLabel("State"));
- p2.add(new JTextField());
- p2.add(new JLabel("Postal Code"));
- p2.add(new JTextField(10), "growx 0, wrap");
- p2.add(new JLabel("Country"));
- p2.add(new JTextField(), "wrap 15");
-
- p2.add(createButton("New"), "tag other, span, split");
- p2.add(createButton("Delete"), "tag other");
- p2.add(createButton("Edit"), "tag other");
- p2.add(createButton("Save"), "tag other");
- p2.add(createButton("Cancel"), "tag cancel, wrap push");
-
- tabbedPane.addTab("Layout Showdown (improved)", p2);
-
-
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "JPanel p = createTabPanel(new MigLayout(\"\", \"[]15[][grow,fill]15[grow]\"));\n" +
- "\n" +
- "JScrollPane list1 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" +
- "\n" +
- "p.add(list1, \"spany, growy, wmin 150\");\n" +
- "p.add(new JLabel(\"Last Name\"));\n" +
- "p.add(new JTextField());\n" +
- "p.add(new JLabel(\"First Name\"), \"split\"); // split divides the cell\n" +
- "p.add(new JTextField(), \"growx, wrap\");\n" +
- "p.add(new JLabel(\"Phone\"));\n" +
- "p.add(new JTextField());\n" +
- "p.add(new JLabel(\"Email\"), \"split\");\n" +
- "p.add(new JTextField(), \"growx, wrap\");\n" +
- "p.add(new JLabel(\"Address 1\"));\n" +
- "p.add(new JTextField(), \"span, growx\"); // span merges cells\n" +
- "p.add(new JLabel(\"Address 2\"));\n" +
- "p.add(new JTextField(), \"span, growx\");\n" +
- "p.add(new JLabel(\"City\"));\n" +
- "p.add(new JTextField(), \"wrap\"); // wrap continues on next line\n" +
- "p.add(new JLabel(\"State\"));\n" +
- "p.add(new JTextField());\n" +
- "p.add(new JLabel(\"Postal Code\"), \"split\");\n" +
- "p.add(new JTextField(), \"growx, wrap\");\n" +
- "p.add(new JLabel(\"Country\"));\n" +
- "p.add(new JTextField(), \"wrap 15\");\n" +
- "\n" +
- "p.add(createButton(\"New\"), \"span, split, align left\");\n" +
- "p.add(createButton(\"Delete\"), \"\");\n" +
- "p.add(createButton(\"Edit\"), \"\");\n" +
- "p.add(createButton(\"Save\"), \"\");\n" +
- "p.add(createButton(\"Cancel\"), \"wrap push\");\n" +
- "\n" +
- "tabbedPane.addTab(\"Layout Showdown (pure)\", p);" +
- "\n" +
- "\t\t// Fixed version *******************************************\n" +
- "JPanel p2 = createTabPanel(new MigLayout(\"\", \"[]15[][grow,fill]15[][grow,fill]\")); // Makes the background gradient\n" +
- "\n" +
- "// References to text fields not stored to reduce code clutter.\n" +
- "\n" +
- "JScrollPane list2 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" +
- "p2.add(list2, \"spany, growy, wmin 150\");\n" +
- "p2.add(new JLabel(\"Last Name\"));\n" +
- "p2.add(new JTextField());\n" +
- "p2.add(new JLabel(\"First Name\"));\n" +
- "p2.add(new JTextField(), \"wrap\");\n" +
- "p2.add(new JLabel(\"Phone\"));\n" +
- "p2.add(new JTextField());\n" +
- "p2.add(new JLabel(\"Email\"));\n" +
- "p2.add(new JTextField(), \"wrap\");\n" +
- "p2.add(new JLabel(\"Address 1\"));\n" +
- "p2.add(new JTextField(), \"span\");\n" +
- "p2.add(new JLabel(\"Address 2\"));\n" +
- "p2.add(new JTextField(), \"span\");\n" +
- "p2.add(new JLabel(\"City\"));\n" +
- "p2.add(new JTextField(), \"wrap\");\n" +
- "p2.add(new JLabel(\"State\"));\n" +
- "p2.add(new JTextField());\n" +
- "p2.add(new JLabel(\"Postal Code\"));\n" +
- "p2.add(new JTextField(10), \"growx 0, wrap\");\n" +
- "p2.add(new JLabel(\"Country\"));\n" +
- "p2.add(new JTextField(), \"wrap 15\");\n" +
- "\n" +
- "p2.add(createButton(\"New\"), \"tag other, span, split\");\n" +
- "p2.add(createButton(\"Delete\"), \"tag other\");\n" +
- "p2.add(createButton(\"Edit\"), \"tag other\");\n" +
- "p2.add(createButton(\"Save\"), \"tag other\");\n" +
- "p2.add(createButton(\"Cancel\"), \"tag cancel, wrap push\");\n" +
- "\n" +
- "tabbedPane.addTab(\"Layout Showdown (improved)\", p2);");
-
- return tabbedPane;
- }
-
- public JComponent createWelcome()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- MigLayout lm = new MigLayout("ins 20, fill", "", "[grow]unrel[]");
-
- JPanel mainPanel = createTabPanel(lm);
-
- String s = "MigLayout's main purpose is to make layouts for SWT and Swing, and possibly other frameworks, much more powerful and a lot easier to create, especially for manual coding.\n\n" +
- "The motto is: \"MigLayout makes complex layouts easy and normal layouts one-liners.\"\n\n" +
- "The layout engine is very flexible and advanced, something that is needed to make it simple to use yet handle almost all layout use-cases.\n\n" +
- "MigLayout can handle all layouts that the commonly used Swing Layout Managers can handle and this with a lot of extra features. " +
- "It also incorporates most, if not all, of the open source alternatives FormLayout's and TableLayout's functionality." +
- "\n\n\nThanks to Karsten Lentzsch of JGoodies.com for allowing the reuse of the main demo application layout and for his inspiring talks that led to this layout Manager." +
- "\n\n\nMikael Grev\n" +
- "MiG InfoCom AB\n" +
- "miglayout@miginfocom.com";
-
- JTextArea textArea = new JTextArea(s);
- textArea.setEditable(false);
- textArea.setSize(400, 400);
-
- if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.WINDOWS_XP)
- textArea.setFont(new Font("tahoma", Font.BOLD, 11));
-
- textArea.setOpaque(OPAQUE);
- textArea.setWrapStyleWord(true);
- textArea.setLineWrap(true);
-
- JLabel label = new JLabel("You can Right Click any Component or Container to change the constraints for it!");
- label.setForeground(new Color(200, 0, 0));
-
- mainPanel.add(textArea, "w 500:pref,ay top,grow,wrap");
- mainPanel.add(label, "growx");
- label.setFont(label.getFont().deriveFont(Font.BOLD));
-
- tabbedPane.addTab("Welcome", mainPanel);
-
- setSource("");
-
- return tabbedPane;
- }
-
- public JComponent createVisual_Bounds()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // "NON"-corrected bounds
- JPanel p1 = createTabPanel(new MigLayout("fill, ins 3, novisualpadding"));
- p1.setBorder(new LineBorder(Color.BLACK));
-
- JTabbedPane demoPane2 = new JTabbedPane();
- JPanel demoPanel2 = new JPanel();
- demoPanel2.setBackground(Color.WHITE);
- demoPane2.addTab("Demo Tab", demoPanel2);
-
- p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
- p1.add(demoPane2, "grow, aligny bottom");
- p1.add(createTextField("A JTextField", 100), "grow, aligny bottom, wmin 100");
- p1.add(createTextArea("A JTextArea", 1, 100), "newline,grow, aligny bottom, wmin 100");
- p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
- p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
-
- JPanel p2 = createTabPanel(new MigLayout("center,center,fill,ins 3"));
- p2.setBorder(new LineBorder(Color.BLACK));
-
- JTabbedPane demoPane = new JTabbedPane();
- JPanel demoPanel = new JPanel();
- demoPanel.setBackground(Color.WHITE);
- demoPane.addTab("Demo Tab", demoPanel);
-
- p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
- p2.add(demoPane, "grow, aligny bottom");
- p2.add(createTextField("A JTextField", 100), "grow, aligny bottom, wmin 100");
- p2.add(createTextArea("A JTextArea", 1, 100), "newline,grow, aligny bottom, wmin 100");
- p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
- p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100");
-
- tabbedPane.addTab("Visual Bounds (Not Corrected)", p1);
- tabbedPane.addTab("Visual Bounds (Corrected on XP)", p2);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// \"NON\"-corrected bounds\n" +
- "JPanel p1 = createTabPanel(new MigLayout(\"fill, ins 3, novisualpadding\"));\n" +
- "p1.setBorder(new LineBorder(Color.BLACK));\n" +
- "\n" +
- "JTabbedPane demoPane2 = new JTabbedPane();\n" +
- "JPanel demoPanel2 = new JPanel();\n" +
- "demoPanel2.setBackground(Color.WHITE);\n" +
- "demoPane2.addTab(\"Demo Tab\", demoPanel2);\n" +
- "\n" +
- "p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
- "p1.add(demoPane2, \"grow, aligny bottom\");\n" +
- "p1.add(createTextField(\"A JTextField\", 100), \"grow, aligny bottom, wmin 100\");\n" +
- "p1.add(createTextArea(\"A JTextArea\", 1, 100), \"newline,grow, aligny bottom, wmin 100\");\n" +
- "p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
- "p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
- "\n" +
- "JPanel p2 = createTabPanel(new MigLayout(\"center,center,fill,ins 3\"));\n" +
- "p2.setBorder(new LineBorder(Color.BLACK));\n" +
- "\n" +
- "JTabbedPane demoPane = new JTabbedPane();\n" +
- "JPanel demoPanel = new JPanel();\n" +
- "demoPanel.setBackground(Color.WHITE);\n" +
- "demoPane.addTab(\"Demo Tab\", demoPanel);\n" +
- "\n" +
- "p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
- "p2.add(demoPane, \"grow, aligny bottom\");\n" +
- "p2.add(createTextField(\"A JTextField\", 100), \"grow, aligny bottom, wmin 100\");\n" +
- "p2.add(createTextArea(\"A JTextArea\", 1, 100), \"newline,grow, aligny bottom, wmin 100\");\n" +
- "p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
- "p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" +
- "\n" +
- "tabbedPane.addTab(\"Visual Bounds (Not Corrected)\", p1);\n" +
- "tabbedPane.addTab(\"Visual Bounds (Corrected on XP)\", p2);");
-
- return tabbedPane;
- }
-
- public JComponent createDocking()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- JPanel p1 = createTabPanel(new MigLayout("fill"));
-
- p1.add(createPanel("1. North"), "north");
- p1.add(createPanel("2. West"), "west");
- p1.add(createPanel("3. East"), "east");
- p1.add(createPanel("4. South"), "south");
-
- String[][] data = new String[20][6];
- for (int r = 0; r < data.length; r++) {
- data[r] = new String[6];
- for (int c = 0; c < data[r].length; c++)
- data[r][c] = "Cell " + (r + 1) + ", " + (c + 1);
- }
- JTable table = new JTable(data, new String[] {"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6"});
- p1.add(new JScrollPane(table), "grow");
-
- JPanel p2 = createTabPanel(new MigLayout("fill", "[c]", ""));
-
- p2.add(createPanel("1. North"), "north");
- p2.add(createPanel("2. North"), "north");
- p2.add(createPanel("3. West"), "west");
- p2.add(createPanel("4. West"), "west");
- p2.add(createPanel("5. South"), "south");
- p2.add(createPanel("6. East"), "east");
- p2.add(createButton("7. Normal"));
- p2.add(createButton("8. Normal"));
- p2.add(createButton("9. Normal"));
-
- JPanel p3 = createTabPanel(new MigLayout());
-
- p3.add(createPanel("1. North"), "north");
- p3.add(createPanel("2. South"), "south");
- p3.add(createPanel("3. West"), "west");
- p3.add(createPanel("4. East"), "east");
- p3.add(createButton("5. Normal"));
-
- JPanel p4 = createTabPanel(new MigLayout());
-
- p4.add(createPanel("1. North"), "north");
- p4.add(createPanel("2. North"), "north");
- p4.add(createPanel("3. West"), "west");
- p4.add(createPanel("4. West"), "west");
- p4.add(createPanel("5. South"), "south");
- p4.add(createPanel("6. East"), "east");
- p4.add(createButton("7. Normal"));
- p4.add(createButton("8. Normal"));
- p4.add(createButton("9. Normal"));
-
- JPanel p5 = createTabPanel(new MigLayout("fillx", "[c]", ""));
-
- p5.add(createPanel("1. North"), "north");
- p5.add(createPanel("2. North"), "north");
- p5.add(createPanel("3. West"), "west");
- p5.add(createPanel("4. West"), "west");
- p5.add(createPanel("5. South"), "south");
- p5.add(createPanel("6. East"), "east");
- p5.add(createButton("7. Normal"));
- p5.add(createButton("8. Normal"));
- p5.add(createButton("9. Normal"));
-
- JPanel p6 = createTabPanel(new MigLayout("fill", "", ""));
-
- Random rand = new Random();
- String[] sides = {"north", "east", "south", "west"};
- for (int i = 0; i < 20; i++) {
- int side = rand.nextInt(4);
- p6.add(createPanel((i + 1) + " " + sides[side]), sides[side]);
- }
- p6.add(createPanel("I'm in the Center!"), "dock center");
-
- tabbedPane.addTab("Docking 1 (fill)", p1);
- tabbedPane.addTab("Docking 2 (fill)", p2);
- tabbedPane.addTab("Docking 3", p3);
- tabbedPane.addTab("Docking 4", p4);
- tabbedPane.addTab("Docking 5 (fillx)", p5);
- tabbedPane.addTab("Random Docking", new JScrollPane(p6));
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "JPanel p1 = createTabPanel(new MigLayout(\"fill\"));\n" +
- "\n" +
- "p1.add(createPanel(\"1. North\"), \"north\");\n" +
- "p1.add(createPanel(\"2. West\"), \"west\");\n" +
- "p1.add(createPanel(\"3. East\"), \"east\");\n" +
- "p1.add(createPanel(\"4. South\"), \"south\");\n" +
- "\n" +
- "String[][] data = new String[20][6];\n" +
- "for (int r = 0; r < data.length; r++) {\n" +
- "\tdata[r] = new String[6];\n" +
- "\tfor (int c = 0; c < data[r].length; c++)\n" +
- "\t\tdata[r][c] = \"Cell \" + (r + 1) + \", \" + (c + 1);\n" +
- "}\n" +
- "JTable table = new JTable(data, new String[] {\"Column 1\", \"Column 2\", \"Column 3\", \"Column 4\", \"Column 5\", \"Column 6\"});\n" +
- "p1.add(new JScrollPane(table), \"grow\");\n" +
- "\n" +
- "JPanel p2 = createTabPanel(new MigLayout(\"fill\", \"[c]\", \"\"));\n" +
- "\n" +
- "p2.add(createPanel(\"1. North\"), \"north\");\n" +
- "p2.add(createPanel(\"2. North\"), \"north\");\n" +
- "p2.add(createPanel(\"3. West\"), \"west\");\n" +
- "p2.add(createPanel(\"4. West\"), \"west\");\n" +
- "p2.add(createPanel(\"5. South\"), \"south\");\n" +
- "p2.add(createPanel(\"6. East\"), \"east\");\n" +
- "p2.add(createButton(\"7. Normal\"));\n" +
- "p2.add(createButton(\"8. Normal\"));\n" +
- "p2.add(createButton(\"9. Normal\"));\n" +
- "\n" +
- "JPanel p3 = createTabPanel(new MigLayout());\n" +
- "\n" +
- "p3.add(createPanel(\"1. North\"), \"north\");\n" +
- "p3.add(createPanel(\"2. South\"), \"south\");\n" +
- "p3.add(createPanel(\"3. West\"), \"west\");\n" +
- "p3.add(createPanel(\"4. East\"), \"east\");\n" +
- "p3.add(createButton(\"5. Normal\"));\n" +
- "\n" +
- "JPanel p4 = createTabPanel(new MigLayout());\n" +
- "\n" +
- "p4.add(createPanel(\"1. North\"), \"north\");\n" +
- "p4.add(createPanel(\"2. North\"), \"north\");\n" +
- "p4.add(createPanel(\"3. West\"), \"west\");\n" +
- "p4.add(createPanel(\"4. West\"), \"west\");\n" +
- "p4.add(createPanel(\"5. South\"), \"south\");\n" +
- "p4.add(createPanel(\"6. East\"), \"east\");\n" +
- "p4.add(createButton(\"7. Normal\"));\n" +
- "p4.add(createButton(\"8. Normal\"));\n" +
- "p4.add(createButton(\"9. Normal\"));\n" +
- "\n" +
- "JPanel p5 = createTabPanel(new MigLayout(\"fillx\", \"[c]\", \"\"));\n" +
- "\n" +
- "p5.add(createPanel(\"1. North\"), \"north\");\n" +
- "p5.add(createPanel(\"2. North\"), \"north\");\n" +
- "p5.add(createPanel(\"3. West\"), \"west\");\n" +
- "p5.add(createPanel(\"4. West\"), \"west\");\n" +
- "p5.add(createPanel(\"5. South\"), \"south\");\n" +
- "p5.add(createPanel(\"6. East\"), \"east\");\n" +
- "p5.add(createButton(\"7. Normal\"));\n" +
- "p5.add(createButton(\"8. Normal\"));\n" +
- "p5.add(createButton(\"9. Normal\"));\n" +
- "\n" +
- "JPanel p6 = createTabPanel(new MigLayout(\"fill\", \"\", \"\"));\n" +
- "\n" +
- "Random rand = new Random();\n" +
- "String[] sides = {\"north\", \"east\", \"south\", \"west\"};\n" +
- "for (int i = 0; i < 20; i++) {\n" +
- "\tint side = rand.nextInt(4);\n" +
- "\tp6.add(createPanel((i + 1) + \" \" + sides[side]), sides[side]);\n" +
- "}\n" +
- "p6.add(createButton(\"I'm in the middle!\"), \"grow\");\n" +
- "\n" +
- "tabbedPane.addTab(\"Docking 1 (fill)\", p1);\n" +
- "tabbedPane.addTab(\"Docking 2 (fill)\", p2);\n" +
- "tabbedPane.addTab(\"Docking 3\", p3);\n" +
- "tabbedPane.addTab(\"Docking 4\", p4);\n" +
- "tabbedPane.addTab(\"Docking 5 (fillx)\", p5);\n" +
- "tabbedPane.addTab(\"Docking Spiral\", new JScrollPane(p6));");
-
- return tabbedPane;
- }
-
- public JComponent createAbsolute_Position()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // Pos tab
- final JPanel posPanel = createTabPanel(new MigLayout());
-
- posPanel.add(createButton(), "pos 0.5al 0al");
- posPanel.add(createButton(), "pos 1al 0al");
- posPanel.add(createButton(), "pos 0.5al 0.5al");
- posPanel.add(createButton(), "pos 5in 45lp");
- posPanel.add(createButton(), "pos 0.5al 0.5al");
- posPanel.add(createButton(), "pos 0.5al 1.0al");
- posPanel.add(createButton(), "pos 1al .25al");
- posPanel.add(createButton(), "pos visual.x2-pref visual.y2-pref");
- posPanel.add(createButton(), "pos 1al -1in");
- posPanel.add(createButton(), "pos 100 100");
- posPanel.add(createButton(), "pos (10+(20*3lp)) 200");
- posPanel.add(createButton("Drag Window! (pos 500-container.xpos 500-container.ypos)"),
- "pos 500-container.xpos 500-container.ypos");
-
- // Bounds tab
- JPanel boundsPanel = createTabPanel(new MigLayout());
-
- String constr = "pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2";
- JLabel southLabel = createLabel(constr, SwingConstants.CENTER);
- southLabel.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));
- southLabel.setBackground(new Color(200, 200, 255, benchRuns == 0 ? 70 : 255));
- southLabel.setOpaque(true);
- southLabel.setFont(southLabel.getFont().deriveFont(Font.BOLD));
- boundsPanel.add(southLabel, constr);
-
- boundsPanel.add(createButton(), "pos 0 0 container.x2 n");
- boundsPanel.add(createButton(), "pos visual.x 40 visual.x2 70");
- boundsPanel.add(createButton(), "pos visual.x 100 visual.x2 p");
- boundsPanel.add(createButton(), "pos 0.1al 0.4al n (visual.y2 - 10)");
- boundsPanel.add(createButton(), "pos 0.9al 0.4al n visual.y2-10");
- boundsPanel.add(createButton(), "pos 0.5al 0.5al, pad 3 0 -3 0");
- boundsPanel.add(createButton(), "pos n n 50% 50%");
- boundsPanel.add(createButton(), "pos 50% 50% n n");
- boundsPanel.add(createButton(), "pos 50% n n 50%");
- boundsPanel.add(createButton(), "pos n 50% 50% n");
-
- tabbedPane.addTab("X Y Positions", posPanel);
- tabbedPane.addTab("X1 Y1 X2 Y2 Bounds", boundsPanel);
-
- // Glass pane tab
- if (benchRuns == 0) {
- final JPanel glassPanel = createTabPanel(new MigLayout("align c c, ins 0"));
- final JButton butt = createButton("Press me!!");
- glassPanel.add(butt);
-
- butt.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- butt.setEnabled(false);
- final JPanel bg = new JPanel(new MigLayout("align c c,fill")) {
- public void paint(Graphics g)
- {
- g.setColor(getBackground());
- g.fillRect(0, 0, getWidth(), getHeight());
- super.paint(g);
- }
- };
- bg.setOpaque(OPAQUE);
- configureActiveComponet(bg);
-
- final JLabel label = createLabel("You don't need a GlassPane to be cool!");
- label.setFont(label.getFont().deriveFont(30f));
- label.setForeground(new Color(255, 255, 255, 0));
- bg.add(label, "align 50% 30%");
-
- glassPanel.add(bg, "pos visual.x visual.y visual.x2 visual.y2", 0);
- final long startTime = System.nanoTime();
- final long endTime = startTime + 500000000L;
-
- glassPanel.revalidate();
-
- final javax.swing.Timer timer = new Timer(25, null);
-
- timer.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- long now = System.nanoTime();
- int alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300);
- if (alpha < 150)
- bg.setBackground(new Color(100, 100, 100, alpha));
-
- if (alpha > 150 && alpha < 405) {
- label.setForeground(new Color(255, 255, 255, (alpha - 150)));
- bg.repaint();
- }
- if (alpha > 405)
- timer.stop();
- }
- });
- timer.start();
- }
- });
- tabbedPane.addTab("GlassPane Substitute", glassPanel);
- addComponentListener(new ComponentAdapter() {
- public void componentMoved(ComponentEvent e) {
- if (posPanel.isDisplayable()) {
- posPanel.revalidate();
- } else {
- removeComponentListener(this);
- }
- }
- });
- }
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// Pos tab\n" +
- "final JPanel posPanel = createTabPanel(new MigLayout());\n" +
- "\n" +
- "posPanel.add(createButton(), \"pos 0.5al 0al\");\n" +
- "posPanel.add(createButton(), \"pos 1al 0al\");\n" +
- "posPanel.add(createButton(), \"pos 0.5al 0.5al\");\n" +
- "posPanel.add(createButton(), \"pos 5in 45lp\");\n" +
- "posPanel.add(createButton(), \"pos 0.5al 0.5al\");\n" +
- "posPanel.add(createButton(), \"pos 0.5al 1.0al\");\n" +
- "posPanel.add(createButton(), \"pos 1al .25al\");\n" +
- "posPanel.add(createButton(), \"pos visual.x2-pref visual.y2-pref\");\n" +
- "posPanel.add(createButton(), \"pos 1al -1in\");\n" +
- "posPanel.add(createButton(), \"pos 100 100\");\n" +
- "posPanel.add(createButton(), \"pos (10+(20*3lp)) 200\");\n" +
- "posPanel.add(createButton(\"Drag Window! (pos 500-container.xpos 500-container.ypos)\"),\n" +
- " \"pos 500-container.xpos 500-container.ypos\");\n" +
- "\n" +
- "// Bounds tab\n" +
- "JPanel boundsPanel = createTabPanel(new MigLayout());\n" +
- "\n" +
- "String constr = \"pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2\";\n" +
- "JLabel southLabel = createLabel(constr, SwingConstants.CENTER);\n" +
- "southLabel.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));\n" +
- "southLabel.setBackground(new Color(200, 200, 255, 70));\n" +
- "southLabel.setOpaque(true);\n" +
- "southLabel.setFont(southLabel.getFont().deriveFont(Font.BOLD));\n" +
- "boundsPanel.add(southLabel, constr);\n" +
- "\n" +
- "boundsPanel.add(createButton(), \"pos 0 0 container.x2 n\");\n" +
- "boundsPanel.add(createButton(), \"pos visual.x 40 visual.x2 70\");\n" +
- "boundsPanel.add(createButton(), \"pos visual.x 100 visual.x2 p\");\n" +
- "boundsPanel.add(createButton(), \"pos 0.1al 0.4al n visual.y2-10\");\n" +
- "boundsPanel.add(createButton(), \"pos 0.9al 0.4al n visual.y2-10\");\n" +
- "boundsPanel.add(createButton(), \"pos 0.5al 0.5al, pad 3 0 -3 0\");\n" +
- "boundsPanel.add(createButton(), \"pos n n 50% 50%\");\n" +
- "boundsPanel.add(createButton(), \"pos 50% 50% n n\");\n" +
- "boundsPanel.add(createButton(), \"pos 50% n n 50%\");\n" +
- "boundsPanel.add(createButton(), \"pos n 50% 50% n\");\n" +
- "\n" +
- "// Glass pane tab\n" +
- "final JPanel glassPanel = createTabPanel(new MigLayout(\"align c c, ins 0\"));\n" +
- "final JButton butt = createButton(\"Press me!!\");\n" +
- "glassPanel.add(butt);\n" +
- "\n" +
- "butt.addActionListener(new ActionListener()\t\t{\n" +
- "\tpublic void actionPerformed(ActionEvent e)\n" +
- "\t{\n" +
- "\t\tbutt.setEnabled(false);\n" +
- "\t\tfinal JPanel bg = new JPanel(new MigLayout(\"align c c,fill\")) {\n" +
- "\t\t\tpublic void paint(Graphics g)\n" +
- "\t\t\t{\n" +
- "\t\t\t\tg.setColor(getBackground());\n" +
- "\t\t\t\tg.fillRect(0, 0, getWidth(), getHeight());\n" +
- "\t\t\t\tsuper.paint(g);\n" +
- "\t\t\t}\n" +
- "\t\t};\n" +
- "\t\tbg.setOpaque(OPAQUE);\n" +
- "\t\tconfigureActiveComponet(bg);\n" +
- "\n" +
- "\t\tfinal JLabel label = createLabel(\"You don't need a GlassPane to be cool!\");\n" +
- "\t\tlabel.setFont(label.getFont().deriveFont(30f));\n" +
- "\t\tlabel.setForeground(new Color(255, 255, 255, 0));\n" +
- "\t\tbg.add(label, \"align 50% 30%\");\n" +
- "\n" +
- "\t\tglassPanel.add(bg, \"pos visual.x visual.y visual.x2 visual.y2\", 0);\n" +
- "\t\tfinal long startTime = System.nanoTime();\n" +
- "\t\tfinal long endTime = startTime + 500000000L;\n" +
- "\n" +
- "\t\tglassPanel.revalidate();\n" +
- "\n" +
- "\t\tfinal javax.swing.Timer timer = new Timer(25, null);\n" +
- "\n" +
- "\t\ttimer.addActionListener(new ActionListener() {\n" +
- "\t\t\tpublic void actionPerformed(ActionEvent e)\n" +
- "\t\t\t{\n" +
- "\t\t\t\tlong now = System.nanoTime();\n" +
- "\t\t\t\tint alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300);\n" +
- "\t\t\t\tif (alpha < 150)\n" +
- "\t\t\t\t\tbg.setBackground(new Color(100, 100, 100, alpha));\n" +
- "\n" +
- "\t\t\t\tif (alpha > 150 && alpha < 405) {\n" +
- "\t\t\t\t\tlabel.setForeground(new Color(255, 255, 255, (alpha - 150)));\n" +
- "\t\t\t\t\tbg.repaint();\n" +
- "\t\t\t\t}\n" +
- "\t\t\t\tif (alpha > 405)\n" +
- "\t\t\t\t\ttimer.stop();\n" +
- "\t\t\t}\n" +
- "\t\t});\n" +
- "\t\ttimer.start();\n" +
- "\t}\n" +
- "});\n" +
- "\n" +
- "tabbedPane.addTab(\"X Y Positions\", posPanel);\n" +
- "tabbedPane.addTab(\"X1 Y1 X2 Y2 Bounds\", boundsPanel);\n" +
- "tabbedPane.addTab(\"GlassPane Substitute\", glassPanel);\n" +
- "\n" +
- "addComponentListener(new ComponentAdapter() {\n" +
- "\tpublic void componentMoved(ComponentEvent e) {\n" +
- "\t\tif (posPanel.isDisplayable()) {\n" +
- "\t\t\tposPanel.revalidate();\n" +
- "\t\t} else {\n" +
- "\t\t\tremoveComponentListener(this);\n" +
- "\t\t}\n" +
- "\t}\n" +
- "});");
-
- return tabbedPane;
- }
-
- public JComponent createComponent_Links()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- JPanel linksPanel = createTabPanel(new MigLayout());
-
- // Links tab
- JButton mini = createButton("Mini");
- mini.setMargin(new Insets(0, 1, 0, 1));
- linksPanel.add(mini, "pos null ta.y ta.x2 null");
- linksPanel.add(createTextArea("Components, Please Link to Me!\nMy ID is: 'ta'", 3, 30), "id ta, pos 0.5al 0.5al");
- linksPanel.add(createButton(), "id b1,pos ta.x2 ta.y2");
- linksPanel.add(createButton(), "pos b1.x2+rel b1.y visual.x2 null");
- linksPanel.add(createButton(), "pos ta.x2+rel ta.y visual.x2 null");
- linksPanel.add(createButton(), "pos null ta.y+(ta.h-pref)/2 ta.x-rel null");
- linksPanel.add(createButton(), "pos ta.x ta.y2+100 ta.x2 null");
- linksPanel.add(createCheck("pos (ta.x+indent) (ta.y2+rel)"),
- "pos (ta.x+indent) (ta.y2+rel)");
-
- // External tab
- JPanel externalPanel = createTabPanel(new MigLayout());
-
- JButton extButt = createButton("Bounds Externally Set!");
- extButt.setBounds(250, 130, 200, 40);
- externalPanel.add(extButt, "id ext, external");
- externalPanel.add(createButton(), "pos ext.x2 ext.y2");
- externalPanel.add(createButton(), "pos null null ext.x ext.y");
-
- // Start/End Group tab
- JPanel egPanel = createTabPanel(new MigLayout());
-
- egPanel.add(createButton(), "id b1, endgroupx g1, pos 200 200");
- egPanel.add(createButton(), "id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)");
- egPanel.add(createButton(), "id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)");
- egPanel.add(createButton(), "id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)");
-
- // Group Bounds tab
- JPanel gpPanel = createTabPanel(new MigLayout());
-
- gpPanel.add(createButton(), "id grp1.b1, pos n 0.5al 50% n");
- gpPanel.add(createButton(), "id grp1.b2, pos 50% 0.5al n n");
- gpPanel.add(createButton(), "id grp1.b3, pos 0.5al n n b1.y");
- gpPanel.add(createButton(), "id grp1.b4, pos 0.5al b1.y2 n n");
-
- gpPanel.add(createButton(), "pos n grp1.y2 grp1.x n");
- gpPanel.add(createButton(), "pos n n grp1.x grp1.y");
- gpPanel.add(createButton(), "pos grp1.x2 n n grp1.y");
- gpPanel.add(createButton(), "pos grp1.x2 grp1.y2");
-
- JPanel boundsPanel = new JPanel(null);
- boundsPanel.setBackground(new Color(200, 200, 255));
- gpPanel.add(boundsPanel, "pos grp1.x grp1.y grp1.x2 grp1.y2");
-
-
- tabbedPane.addTab("Component Links", linksPanel);
- tabbedPane.addTab("External Components", externalPanel);
- tabbedPane.addTab("End Grouping", egPanel);
- tabbedPane.addTab("Group Bounds", gpPanel);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "JPanel linksPanel = createTabPanel(new MigLayout());\n" +
- "\n" +
- "// Links tab\n" +
- "JButton mini = createButton(\"Mini\");\n" +
- "mini.setMargin(new Insets(0, 1, 0, 1));\n" +
- "linksPanel.add(mini, \"pos null ta.y ta.x2 null\");\n" +
- "linksPanel.add(createTextArea(\"Components, Please Link to Me!\\nMy ID is: 'ta'\", 3, 30), \"id ta, pos 0.5al 0.5al\");\n" +
- "linksPanel.add(createButton(), \"id b1,pos ta.x2 ta.y2\");\n" +
- "linksPanel.add(createButton(), \"pos b1.x2+rel b1.y visual.x2 null\");\n" +
- "linksPanel.add(createButton(), \"pos ta.x2+rel ta.y visual.x2 null\");\n" +
- "linksPanel.add(createButton(), \"pos null ta.y+(ta.h-pref)/2 ta.x-rel null\");\n" +
- "linksPanel.add(createButton(), \"pos ta.x ta.y2+100 ta.x2 null\");\n" +
- "linksPanel.add(createCheck(\"pos (ta.x+indent) (ta.y2+rel)\"),\n" +
- " \"pos (ta.x+indent) (ta.y2+rel)\");\n" +
- "\n" +
- "// External tab\n" +
- "JPanel externalPanel = createTabPanel(new MigLayout());\n" +
- "\n" +
- "JButton extButt = createButton(\"Bounds Externally Set!\");\n" +
- "extButt.setBounds(250, 130, 200, 40);\n" +
- "externalPanel.add(extButt, \"id ext, external\");\n" +
- "externalPanel.add(createButton(), \"pos ext.x2 ext.y2\");\n" +
- "externalPanel.add(createButton(), \"pos null null ext.x ext.y\");\n" +
- "\n" +
- "// Start/End Group tab\n" +
- "JPanel egPanel = createTabPanel(new MigLayout());\n" +
- "\n" +
- "egPanel.add(createButton(), \"id b1, endgroupx g1, pos 200 200\");\n" +
- "egPanel.add(createButton(), \"id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)\");\n" +
- "egPanel.add(createButton(), \"id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)\");\n" +
- "egPanel.add(createButton(), \"id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)\");\n" +
- "\n" +
- "// Group Bounds tab\n" +
- "JPanel gpPanel = createTabPanel(new MigLayout());\n" +
- "\n" +
- "gpPanel.add(createButton(), \"id grp1.b1, pos n 0.5al 50% n\");\n" +
- "gpPanel.add(createButton(), \"id grp1.b2, pos 50% 0.5al n n\");\n" +
- "gpPanel.add(createButton(), \"id grp1.b3, pos 0.5al n n b1.y\");\n" +
- "gpPanel.add(createButton(), \"id grp1.b4, pos 0.5al b1.y2 n n\");\n" +
- "\n" +
- "gpPanel.add(createButton(), \"pos n grp1.y2 grp1.x n\");\n" +
- "gpPanel.add(createButton(), \"pos n n grp1.x grp1.y\");\n" +
- "gpPanel.add(createButton(), \"pos grp1.x2 n n grp1.y\");\n" +
- "gpPanel.add(createButton(), \"pos grp1.x2 grp1.y2\");\n" +
- "\n" +
- "JPanel boundsPanel = new JPanel(null);\n" +
- "boundsPanel.setBackground(new Color(200, 200, 255));\n" +
- "gpPanel.add(boundsPanel, \"pos grp1.x grp1.y grp1.x2 grp1.y2\");\n" +
- "\n" +
- "\n" +
- "tabbedPane.addTab(\"Component Links\", linksPanel);\n" +
- "tabbedPane.addTab(\"External Components\", externalPanel);\n" +
- "tabbedPane.addTab(\"End Grouping\", egPanel);\n" +
- "tabbedPane.addTab(\"Group Bounds\", gpPanel);");
-
- return tabbedPane;
- }
-
- public JComponent createFlow_Direction()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- tabbedPane.addTab("Layout: flowx, Cell: flowx", createFlowPanel("", "flowx"));
- tabbedPane.addTab("Layout: flowx, Cell: flowy", createFlowPanel("", "flowy"));
- tabbedPane.addTab("Layout: flowy, Cell: flowx", createFlowPanel("flowy", "flowx"));
- tabbedPane.addTab("Layout: flowy, Cell: flowy", createFlowPanel("flowy", "flowy"));
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "tabbedPane.addTab(\"Layout: flowx, Cell: flowx\", createFlowPanel(\"\", \"flowx\"));\n" +
- "tabbedPane.addTab(\"Layout: flowx, Cell: flowy\", createFlowPanel(\"\", \"flowy\"));\n" +
- "tabbedPane.addTab(\"Layout: flowy, Cell: flowx\", createFlowPanel(\"flowy\", \"flowx\"));\n" +
- "tabbedPane.addTab(\"Layout: flowy, Cell: flowy\", createFlowPanel(\"flowy\", \"flowy\"));" +
- "\n\tpublic JPanel createFlowPanel(String gridFlow, String cellFlow)\n" +
- "\t{\n" +
- "MigLayout lm = new MigLayout(\"center, wrap 3,\" + gridFlow,\n" +
- " \"[110,fill]\",\n" +
- " \"[110,fill]\");\n" +
- "JPanel panel = createTabPanel(lm);\n" +
- "\n" +
- "for (int i = 0; i < 9; i++) {\n" +
- "\tJButton b = createButton(\"\" + (i + 1));\n" +
- "\tb.setFont(b.getFont().deriveFont(20f));\n" +
- "\tpanel.add(b, cellFlow);\n" +
- "}\n" +
- "\n" +
- "JButton b = createButton(\"5:2\");\n" +
- "b.setFont(b.getFont().deriveFont(20f));\n" +
- "panel.add(b, cellFlow + \",cell 1 1\");\n" +
- "\n" +
- "return panel;\n" +
- "\t}");
-
- return tabbedPane;
- }
-
- public JPanel createFlowPanel(String gridFlow, String cellFlow)
- {
- MigLayout lm = new MigLayout("center, wrap 3," + gridFlow,
- "[110,fill]",
- "[110,fill]");
- JPanel panel = createTabPanel(lm);
-
- Font f = panel.getFont().deriveFont(20f);
- for (int i = 0; i < 9; i++) {
- JComponent b = createPanel("" + (i + 1));
- b.setFont(f);
- panel.add(b, cellFlow);
- }
-
- JComponent b = createPanel("5:2");
- b.setFont(f);
- panel.add(b, cellFlow + ",cell 1 1");
-
- return panel;
- }
-
- public JComponent createDebug()
- {
- return createPlainImpl(true);
- }
-
- public JComponent createButton_Bars()
- {
- MigLayout lm = new MigLayout("ins 0 0 15lp 0",
- "[grow]",
- "[grow][baseline,nogrid]");
-
- final JPanel mainPanel = new JPanel(lm);
- final JLabel formatLabel = createLabel("");
- formatLabel.setFont(formatLabel.getFont().deriveFont(Font.BOLD));
- JTabbedPane tabbedPane = new JTabbedPane();
-
- JToggleButton winButt = createToggleButton("Windows");
- JToggleButton macButt = createToggleButton("Mac OS X");
- JButton helpButt = createButton("Help");
-
- if (benchRuns == 0) {
- winButt.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- PlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP);
- formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'");
- ((JPanel) ((JFrame) Frame.getFrames()[0]).getContentPane()).revalidate();
- }
- });
-
- macButt.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- PlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX);
- formatLabel.setText(PlatformDefaults.getButtonOrder());
- ((JPanel) ((JFrame) Frame.getFrames()[0]).getContentPane()).revalidate();
- }
- });
-
- helpButt.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- JOptionPane.showMessageDialog(mainPanel, "See JavaDoc for PlatformConverter.getButtonBarOrder(..) for details on the format string.");
- }
- });
- }
-
- ButtonGroup bg = new ButtonGroup();
- bg.add(winButt);
- bg.add(macButt);
- if (benchRuns == 0) {
- if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.MAC_OSX) {
- macButt.doClick();
- } else {
- winButt.doClick();
- }
- }
-
- tabbedPane.addTab("Buttons", createButtonBarsPanel("help", false));
- tabbedPane.addTab("Buttons with Help2", createButtonBarsPanel("help2", false));
- tabbedPane.addTab("Buttons (Same width)", createButtonBarsPanel("help", true));
-
- mainPanel.add(tabbedPane, "grow,wrap");
-
- mainPanel.add(createLabel("Button Order:"));
- mainPanel.add(formatLabel, "growx");
- mainPanel.add(winButt);
- mainPanel.add(macButt);
- mainPanel.add(helpButt, "gapbefore unrel");
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("MigLayout lm = new MigLayout(\"ins 0 0 15lp 0\",\n" +
- " \"[grow]\",\n" +
- " \"[grow][baseline,nogrid,gap unrelated]\");\n" +
- "\n" +
- "final JPanel mainPanel = new JPanel(lm);\n" +
- "final JLabel formatLabel = createLabel(\"\");\n" +
- "formatLabel.setFont(formatLabel.getFont().deriveFont(Font.BOLD));\n" +
- "JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "JToggleButton winButt = createToggleButton(\"Windows\");\n" +
- "\n" +
- "winButt.addActionListener(new ActionListener() {\n" +
- "\tpublic void actionPerformed(ActionEvent e) {\n" +
- "\t\tPlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP);\n" +
- "\t\tformatLabel.setText(\"'\" + PlatformDefaults.getButtonOrder() + \"'\");\n" +
- "\t\tSwingUtilities.updateComponentTreeUI(mainPanel);\n" +
- "\t}\n" +
- "});\n" +
- "\n" +
- "JToggleButton macButt = createToggleButton(\"Mac OS X\");\n" +
- "macButt.addActionListener(new ActionListener() {\n" +
- "\tpublic void actionPerformed(ActionEvent e) {\n" +
- "\t\tPlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX);\n" +
- "\t\tformatLabel.setText(PlatformDefaults.getButtonOrder());\n" +
- "\t\tSwingUtilities.updateComponentTreeUI(mainPanel);\n" +
- "\t}\n" +
- "});\n" +
- "\n" +
- "JButton helpButt = createButton(\"Help\");\n" +
- "helpButt.addActionListener(new ActionListener() {\n" +
- "\tpublic void actionPerformed(ActionEvent e) {\n" +
- "\t\tJOptionPane.showMessageDialog(mainPanel, \"See JavaDoc for PlatformConverter.getButtonBarOrder(..) for details on the format string.\");\n" +
- "\t}\n" +
- "});\n" +
- "\n" +
- "ButtonGroup bg = new ButtonGroup();\n" +
- "bg.add(winButt);\n" +
- "bg.add(macButt);\n" +
- "winButt.doClick();\n" +
- "\n" +
- "tabbedPane.addTab(\"Buttons\", createButtonBarsPanel(\"help\", false));\n" +
- "tabbedPane.addTab(\"Buttons with Help2\", createButtonBarsPanel(\"help2\", false));\n" +
- "tabbedPane.addTab(\"Buttons (Same width)\", createButtonBarsPanel(\"help\", true));\n" +
- "\n" +
- "mainPanel.add(tabbedPane, \"grow,wrap\");\n" +
- "\n" +
- "mainPanel.add(createLabel(\"Button Order:\"));\n" +
- "mainPanel.add(formatLabel, \"growx\");\n" +
- "mainPanel.add(winButt);\n" +
- "mainPanel.add(macButt);\n" +
- "mainPanel.add(helpButt, \"gapbefore unrel\");");
-
- return mainPanel;
- }
-
- private JComponent createButtonBarsPanel(String helpTag, boolean sizeLocked)
- {
- MigLayout lm = new MigLayout("nogrid, fillx, aligny 100%, gapy unrel");
- JPanel panel = createTabPanel(lm);
-
- // Notice that the order in the rows below does not matter...
- String[][] buttons = new String[][] {
- {"OK"},
- {"No", "Yes"},
- {"Help", "Close"},
- {"OK", "Help"},
- {"OK", "Cancel", "Help"},
- {"OK", "Cancel", "Apply", "Help"},
- {"No", "Yes", "Cancel"},
- {"Help", "< Back", "Forward >", "Cancel"},
- {"Print...", "Cancel", "Help"}
- };
-
- for (int r = 0; r < buttons.length; r++) {
- for (int i = 0; i < buttons[r].length; i++) {
- String txt = buttons[r][i];
- String tag = txt;
-
- if (txt.equals("Help")) {
- tag = helpTag;
- } else if (txt.equals("< Back")) {
- tag = "back";
- } else if (txt.equals("Close")) {
- tag = "cancel";
- } else if (txt.equals("Forward >")) {
- tag = "next";
- } else if (txt.equals("Print...")) {
- tag = "other";
- }
- String wrap = (i == buttons[r].length - 1) ? ",wrap" : "";
- String sizeGroup = sizeLocked ? ("sgx " + r + ",") : "";
- panel.add(createButton(txt), sizeGroup + "tag " + tag + wrap);
- }
- }
- return panel;
- }
-
- public JComponent createOrientation()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- MigLayout lm = new MigLayout("flowy", "[grow,fill]", "[]20[]20[]20[]");
- JPanel mainPanel = createTabPanel(lm);
-
- // Default orientation
- MigLayout defLM = new MigLayout("", "[trailing][grow,fill]", "");
-
- JPanel defPanel = createTabPanel(defLM);
- addSeparator(defPanel, "Default Orientation");
- defPanel.add(createLabel("Level of Trust"));
- defPanel.add(createTextField(""), "span,growx");
- defPanel.add(createLabel("Radar Presentation"));
- defPanel.add(createTextField(""));
- defPanel.add(createTextField(""));
-
- // Right-to-left, Top-to-bottom
- MigLayout rtlLM = new MigLayout("rtl,ttb",
- "[trailing][grow,fill]",
- "");
- JPanel rtlPanel = createTabPanel(rtlLM);
- addSeparator(rtlPanel, "Right to Left");
- rtlPanel.add(createLabel("Level of Trust"));
- rtlPanel.add(createTextField(""), "span,growx");
- rtlPanel.add(createLabel("Radar Presentation"));
- rtlPanel.add(createTextField(""));
- rtlPanel.add(createTextField(""));
-
- // Right-to-left, Bottom-to-top
- MigLayout rtlbLM = new MigLayout("rtl,btt",
- "[trailing][grow,fill]",
- "");
- JPanel rtlbPanel = createTabPanel(rtlbLM);
- addSeparator(rtlbPanel, "Right to Left, Bottom to Top");
- rtlbPanel.add(createLabel("Level of Trust"));
- rtlbPanel.add(createTextField(""), "span,growx");
- rtlbPanel.add(createLabel("Radar Presentation"));
- rtlbPanel.add(createTextField(""));
- rtlbPanel.add(createTextField(""));
-
- // Left-to-right, Bottom-to-top
- MigLayout ltrbLM = new MigLayout("ltr,btt",
- "[trailing][grow,fill]",
- "");
- JPanel ltrbPanel = createTabPanel(ltrbLM);
- addSeparator(ltrbPanel, "Left to Right, Bottom to Top");
- ltrbPanel.add(createLabel("Level of Trust"));
- ltrbPanel.add(createTextField(""), "span,growx");
- ltrbPanel.add(createLabel("Radar Presentation"));
- ltrbPanel.add(createTextField(""));
- ltrbPanel.add(createTextField(""));
-
- mainPanel.add(defPanel);
- mainPanel.add(rtlPanel);
- mainPanel.add(rtlbPanel);
- mainPanel.add(ltrbPanel);
-
- tabbedPane.addTab("Orientation", mainPanel);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "MigLayout lm = new MigLayout(\"flowy\", \"[grow,fill]\", \"[]0[]15lp[]0[]\");\n" +
- "JPanel mainPanel = createTabPanel(lm);\n" +
- "\n" +
- "// Default orientation\n" +
- "MigLayout defLM = new MigLayout(\"\", \"[][grow,fill]\", \"\");\n" +
- "\n" +
- "JPanel defPanel = createTabPanel(defLM);\n" +
- "addSeparator(defPanel, \"Default Orientation\");\n" +
- "defPanel.add(createLabel(\"Level\"));\n" +
- "defPanel.add(createTextField(\"\"), \"span,growx\");\n" +
- "defPanel.add(createLabel(\"Radar\"));\n" +
- "defPanel.add(createTextField(\"\"));\n" +
- "defPanel.add(createTextField(\"\"));\n" +
- "\n" +
- "// Right-to-left, Top-to-bottom\n" +
- "MigLayout rtlLM = new MigLayout(\"rtl,ttb\",\n" +
- " \"[][grow,fill]\",\n" +
- " \"\");\n" +
- "JPanel rtlPanel = createTabPanel(rtlLM);\n" +
- "addSeparator(rtlPanel, \"Right to Left\");\n" +
- "rtlPanel.add(createLabel(\"Level\"));\n" +
- "rtlPanel.add(createTextField(\"\"), \"span,growx\");\n" +
- "rtlPanel.add(createLabel(\"Radar\"));\n" +
- "rtlPanel.add(createTextField(\"\"));\n" +
- "rtlPanel.add(createTextField(\"\"));\n" +
- "\n" +
- "// Right-to-left, Bottom-to-top\n" +
- "MigLayout rtlbLM = new MigLayout(\"rtl,btt\",\n" +
- " \"[][grow,fill]\",\n" +
- " \"\");\n" +
- "JPanel rtlbPanel = createTabPanel(rtlbLM);\n" +
- "addSeparator(rtlbPanel, \"Right to Left, Bottom to Top\");\n" +
- "rtlbPanel.add(createLabel(\"Level\"));\n" +
- "rtlbPanel.add(createTextField(\"\"), \"span,growx\");\n" +
- "rtlbPanel.add(createLabel(\"Radar\"));\n" +
- "rtlbPanel.add(createTextField(\"\"));\n" +
- "rtlbPanel.add(createTextField(\"\"));\n" +
- "\n" +
- "// Left-to-right, Bottom-to-top\n" +
- "MigLayout ltrbLM = new MigLayout(\"ltr,btt\",\n" +
- " \"[][grow,fill]\",\n" +
- " \"\");\n" +
- "JPanel ltrbPanel = createTabPanel(ltrbLM);\n" +
- "addSeparator(ltrbPanel, \"Left to Right, Bottom to Top\");\n" +
- "ltrbPanel.add(createLabel(\"Level\"));\n" +
- "ltrbPanel.add(createTextField(\"\"), \"span,growx\");\n" +
- "ltrbPanel.add(createLabel(\"Radar\"));\n" +
- "ltrbPanel.add(createTextField(\"\"));\n" +
- "ltrbPanel.add(createTextField(\"\"));\n" +
- "\n" +
- "mainPanel.add(defPanel);\n" +
- "mainPanel.add(rtlPanel);\n" +
- "mainPanel.add(rtlbPanel);\n" +
- "mainPanel.add(ltrbPanel);\n" +
- "\n" +
- "tabbedPane.addTab(\"Orientation\", mainPanel);");
-
- return tabbedPane;
- }
-
- public JComponent createCell_Position()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // Absolute grid position
- MigLayout absLM = new MigLayout("",
- "[100:pref,fill]",
- "[100:pref,fill]");
- JPanel absPanel = createTabPanel(absLM);
- absPanel.add(createButton(), "cell 0 0");
- absPanel.add(createButton(), "cell 2 0");
- absPanel.add(createButton(), "cell 3 0");
- absPanel.add(createButton(), "cell 1 1");
- absPanel.add(createButton(), "cell 0 2");
- absPanel.add(createButton(), "cell 2 2");
- absPanel.add(createButton(), "cell 2 2");
-
-
- // Relative grid position with wrap
- MigLayout relAwLM = new MigLayout("wrap",
- "[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]",
- "[100:pref,fill]");
- JPanel relAwPanel = createTabPanel(relAwLM);
- relAwPanel.add(createButton());
- relAwPanel.add(createButton(), "skip");
- relAwPanel.add(createButton());
- relAwPanel.add(createButton(), "skip,wrap");
- relAwPanel.add(createButton());
- relAwPanel.add(createButton(), "skip,split");
- relAwPanel.add(createButton());
-
-
- // Relative grid position with manual wrap
- MigLayout relWLM = new MigLayout("",
- "[100:pref,fill]",
- "[100:pref,fill]");
- JPanel relWPanel = createTabPanel(relWLM);
- relWPanel.add(createButton());
- relWPanel.add(createButton(), "skip");
- relWPanel.add(createButton(), "wrap");
- relWPanel.add(createButton(), "skip,wrap");
- relWPanel.add(createButton());
- relWPanel.add(createButton(), "skip,split");
-
- relWPanel.add(createButton());
-
-
- // Mixed relative and absolute grid position
- MigLayout mixLM = new MigLayout("",
- "[100:pref,fill]",
- "[100:pref,fill]");
- JPanel mixPanel = createTabPanel(mixLM);
- mixPanel.add(createButton());
- mixPanel.add(createButton(), "cell 2 0");
- mixPanel.add(createButton());
- mixPanel.add(createButton(), "cell 1 1,wrap");
- mixPanel.add(createButton());
- mixPanel.add(createButton(), "cell 2 2,split");
- mixPanel.add(createButton());
-
- tabbedPane.addTab("Absolute", absPanel);
- tabbedPane.addTab("Relative + Wrap", relAwPanel);
- tabbedPane.addTab("Relative", relWPanel);
- tabbedPane.addTab("Mixed", mixPanel);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("\t\tJTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "\t\t// Absolute grid position\n" +
- "\t\tMigLayout absLM = new MigLayout(\"\",\n" +
- "\t\t \"[100:pref,fill]\",\n" +
- "\t\t \"[100:pref,fill]\");\n" +
- "\t\tJPanel absPanel = createTabPanel(absLM);\n" +
- "\t\tabsPanel.add(createPanel(), \"cell 0 0\");\n" +
- "\t\tabsPanel.add(createPanel(), \"cell 2 0\");\n" +
- "\t\tabsPanel.add(createPanel(), \"cell 3 0\");\n" +
- "\t\tabsPanel.add(createPanel(), \"cell 1 1\");\n" +
- "\t\tabsPanel.add(createPanel(), \"cell 0 2\");\n" +
- "\t\tabsPanel.add(createPanel(), \"cell 2 2\");\n" +
- "\t\tabsPanel.add(createPanel(), \"cell 2 2\");\n" +
- "\n" +
- "\n" +
- "\t\t// Relative grid position with wrap\n" +
- "\t\tMigLayout relAwLM = new MigLayout(\"wrap\",\n" +
- "\t\t \"[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]\",\n" +
- "\t\t \"[100:pref,fill]\");\n" +
- "\t\tJPanel relAwPanel = createTabPanel(relAwLM);\n" +
- "\t\trelAwPanel.add(createPanel());\n" +
- "\t\trelAwPanel.add(createPanel(), \"skip\");\n" +
- "\t\trelAwPanel.add(createPanel());\n" +
- "\t\trelAwPanel.add(createPanel(), \"skip,wrap\");\n" +
- "\t\trelAwPanel.add(createPanel());\n" +
- "\t\trelAwPanel.add(createPanel(), \"skip,split\");\n" +
- "\t\trelAwPanel.add(createPanel());\n" +
- "\n" +
- "\n" +
- "\t\t// Relative grid position with manual wrap\n" +
- "\t\tMigLayout relWLM = new MigLayout(\"\",\n" +
- "\t\t \"[100:pref,fill]\",\n" +
- "\t\t \"[100:pref,fill]\");\n" +
- "\t\tJPanel relWPanel = createTabPanel(relWLM);\n" +
- "\t\trelWPanel.add(createPanel());\n" +
- "\t\trelWPanel.add(createPanel(), \"skip\");\n" +
- "\t\trelWPanel.add(createPanel(), \"wrap\");\n" +
- "\t\trelWPanel.add(createPanel(), \"skip,wrap\");\n" +
- "\t\trelWPanel.add(createPanel());\n" +
- "\t\trelWPanel.add(createPanel(), \"skip,split\");\n" +
- "\n" +
- "\t\trelWPanel.add(createPanel());\n" +
- "\n" +
- "\n" +
- "\t\t// Mixed relative and absolute grid position\n" +
- "\t\tMigLayout mixLM = new MigLayout(\"\",\n" +
- "\t\t \"[100:pref,fill]\",\n" +
- "\t\t \"[100:pref,fill]\");\n" +
- "\t\tJPanel mixPanel = createTabPanel(mixLM);\n" +
- "\t\tmixPanel.add(createPanel());\n" +
- "\t\tmixPanel.add(createPanel(), \"cell 2 0\");\n" +
- "\t\tmixPanel.add(createPanel());\n" +
- "\t\tmixPanel.add(createPanel(), \"cell 1 1,wrap\");\n" +
- "\t\tmixPanel.add(createPanel());\n" +
- "\t\tmixPanel.add(createPanel(), \"cell 2 2,split\");\n" +
- "\t\tmixPanel.add(createPanel());\n" +
- "\n" +
- "\t\ttabbedPane.addTab(\"Absolute\", absPanel);\n" +
- "\t\ttabbedPane.addTab(\"Relative + Wrap\", relAwPanel);\n" +
- "\t\ttabbedPane.addTab(\"Relative\", relWPanel);\n" +
- "\t\ttabbedPane.addTab(\"Mixed\", mixPanel);");
-
- return tabbedPane;
- }
-
- public JComponent createPlain()
- {
- return createPlainImpl(false);
- }
-
- private JComponent createPlainImpl(boolean debug)
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- MigLayout lm = new MigLayout((debug && benchRuns == 0 ? "debug, inset 20" : "ins 20"), "[para]0[][100lp, fill][60lp][95lp, fill]", "");
- JPanel panel = createTabPanel(lm);
-
- addSeparator(panel, "Manufacturer");
-
- panel.add(createLabel("Company"), "skip");
- panel.add(createTextField(""), "span, growx");
- panel.add(createLabel("Contact"), "skip");
- panel.add(createTextField(""), "span, growx");
- panel.add(createLabel("Order No"), "skip");
- panel.add(createTextField(15), "wrap para");
-
- addSeparator(panel, "Inspector");
-
- panel.add(createLabel("Name"), "skip");
- panel.add(createTextField(""), "span, growx");
- panel.add(createLabel("Reference No"), "skip");
- panel.add(createTextField(""), "wrap");
- panel.add(createLabel("Status"), "skip");
- panel.add(createCombo(new String[] {"In Progress", "Finnished", "Released"}), "wrap para");
-
- addSeparator(panel, "Ship");
-
- panel.add(createLabel("Shipyard"), "skip");
- panel.add(createTextField(""), "span, growx");
- panel.add(createLabel("Register No"), "skip");
- panel.add(createTextField(""));
- panel.add(createLabel("Hull No"), "right");
- panel.add(createTextField(15), "wrap");
- panel.add(createLabel("Project Type"), "skip");
- panel.add(createCombo(new String[] {"New Building", "Convention", "Repair"}));
-
- if (debug)
- panel.add(createLabel("Red is cell bounds. Blue is component bounds."), "newline,ax left,span,gaptop 40,");
-
- tabbedPane.addTab("Plain", panel);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "MigLayout lm = new MigLayout((debug && benchRuns == 0 ? \"debug, inset 20\" : \"ins 20\"), \"[para]0[][100lp, fill][60lp][95lp, fill]\", \"\");\n" +
- "JPanel panel = createTabPanel(lm);\n" +
- "\n" +
- "addSeparator(panel, \"Manufacturer\");\n" +
- "\n" +
- "panel.add(createLabel(\"Company\"), \"skip\");\n" +
- "panel.add(createTextField(\"\"), \"span, growx\");\n" +
- "panel.add(createLabel(\"Contact\"), \"skip\");\n" +
- "panel.add(createTextField(\"\"), \"span, growx\");\n" +
- "panel.add(createLabel(\"Order No\"), \"skip\");\n" +
- "panel.add(createTextField(15), \"wrap para\");\n" +
- "\n" +
- "addSeparator(panel, \"Inspector\");\n" +
- "\n" +
- "panel.add(createLabel(\"Name\"), \"skip\");\n" +
- "panel.add(createTextField(\"\"), \"span, growx\");\n" +
- "panel.add(createLabel(\"Reference No\"), \"skip\");\n" +
- "panel.add(createTextField(\"\"), \"wrap\");\n" +
- "panel.add(createLabel(\"Status\"), \"skip\");\n" +
- "panel.add(createCombo(new String[] {\"In Progress\", \"Finnished\", \"Released\"}), \"wrap para\");\n" +
- "\n" +
- "addSeparator(panel, \"Ship\");\n" +
- "\n" +
- "panel.add(createLabel(\"Shipyard\"), \"skip\");\n" +
- "panel.add(createTextField(\"\"), \"span, growx\");\n" +
- "panel.add(createLabel(\"Register No\"), \"skip\");\n" +
- "panel.add(createTextField(\"\"));\n" +
- "panel.add(createLabel(\"Hull No\"), \"right\");\n" +
- "panel.add(createTextField(15), \"wrap\");\n" +
- "panel.add(createLabel(\"Project Type\"), \"skip\");\n" +
- "panel.add(createCombo(new String[] {\"New Building\", \"Convention\", \"Repair\"}));\n" +
- "\n" +
- "if (debug)\n" +
- "\tpanel.add(createLabel(\"Red is cell bounds. Blue is component bounds.\"), \"newline,ax left,span,gaptop 40,\");\n" +
- "\n" +
- "tabbedPane.addTab(\"Plain\", panel);");
-
- return tabbedPane;
- }
-
- public JComponent createBound_Sizes()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1
- String colConstr = i == 0 ? "[right][200]" : "[right, 75lp:pref][200]";
-
- MigLayout LM1 = new MigLayout("wrap", colConstr, "");
- JPanel panel1 = createTabPanel(LM1);
- panel1.add(createLabel("File Number:"));
- panel1.add(createTextField(""), "growx");
- panel1.add(createLabel("RFQ Number:"));
- panel1.add(createTextField(""), "growx");
- panel1.add(createLabel("Entry Date:"));
- panel1.add(createTextField(6));
- panel1.add(createLabel("Sales Person:"));
- panel1.add(createTextField(""), "growx");
-
- MigLayout LM2 = new MigLayout("wrap", colConstr, "");
- JPanel panel2 = createTabPanel(LM2);
- panel2.add(createLabel("Shipper:"));
- panel2.add(createTextField(6), "split 2");
- panel2.add(createTextField(""), "growx");
- panel2.add(createLabel("Consignee:"));
- panel2.add(createTextField(6), "split 2");
- panel2.add(createTextField(""), "growx");
- panel2.add(createLabel("Departure:"));
- panel2.add(createTextField(6), "split 2");
- panel2.add(createTextField(""), "growx");
- panel2.add(createLabel("Destination:"));
- panel2.add(createTextField(6), "split 2");
- panel2.add(createTextField(""), "growx");
-
- tabbedPane.addTab(i == 0 ? "Jumping 1" : "Stable 1", panel1);
- tabbedPane.addTab(i == 0 ? "Jumping 2" : "Stable 2", panel2);
- }
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1\n" +
- "\tString colConstr = i == 0 ? \"[right][200]\" : \"[right, 75lp:pref][200]\";\n" +
- "\n" +
- "\tMigLayout LM1 = new MigLayout(\"wrap\", colConstr, \"\");\n" +
- "\tJPanel panel1 = createTabPanel(LM1);\n" +
- "\tpanel1.add(createLabel(\"File Number:\"));\n" +
- "\tpanel1.add(createTextField(\"\"), \"growx\");\n" +
- "\tpanel1.add(createLabel(\"RFQ Number:\"));\n" +
- "\tpanel1.add(createTextField(\"\"), \"growx\");\n" +
- "\tpanel1.add(createLabel(\"Entry Date:\"));\n" +
- "\tpanel1.add(createTextField(6));\n" +
- "\tpanel1.add(createLabel(\"Sales Person:\"));\n" +
- "\tpanel1.add(createTextField(\"\"), \"growx\");\n" +
- "\n" +
- "\tMigLayout LM2 = new MigLayout(\"wrap\", colConstr, \"\");\n" +
- "\tJPanel panel2 = createTabPanel(LM2);\n" +
- "\tpanel2.add(createLabel(\"Shipper:\"));\n" +
- "\tpanel2.add(createTextField(6), \"split 2\");\n" +
- "\tpanel2.add(createTextField(\"\"), \"growx\");\n" +
- "\tpanel2.add(createLabel(\"Consignee:\"));\n" +
- "\tpanel2.add(createTextField(6), \"split 2\");\n" +
- "\tpanel2.add(createTextField(\"\"), \"growx\");\n" +
- "\tpanel2.add(createLabel(\"Departure:\"));\n" +
- "\tpanel2.add(createTextField(6), \"split 2\");\n" +
- "\tpanel2.add(createTextField(\"\"), \"growx\");\n" +
- "\tpanel2.add(createLabel(\"Destination:\"));\n" +
- "\tpanel2.add(createTextField(6), \"split 2\");\n" +
- "\tpanel2.add(createTextField(\"\"), \"growx\");\n" +
- "\n" +
- "\ttabbedPane.addTab(i == 0 ? \"Jumping 1\" : \"Stable 2\", panel1);\n" +
- "\ttabbedPane.addTab(i == 0 ? \"Jumping 2\" : \"Stable 2\", panel2);\n" +
- "}");
-
- return tabbedPane;
- }
-
- public JComponent createComponent_Sizes()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- MigLayout LM = new MigLayout("wrap", "[right][0:pref,grow]", "");
-
- JPanel panel = createTabPanel(LM);
- JScrollPane descrText = createTextAreaScroll("Use slider to see how the components grow and shrink depending on the constraints set on them.", 0, 0, false);
-
- descrText.setOpaque(OPAQUE);
- descrText.setBorder(new EmptyBorder(10, 10, 10, 10));
- ((JTextArea) descrText.getViewport().getView()).setOpaque(OPAQUE);
- descrText.getViewport().setOpaque(OPAQUE);
-
- JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panel, descrText);
- splitPane.setOpaque(OPAQUE);
- splitPane.setBorder(null);
-
- panel.add(createLabel("\"\""));
- panel.add(createTextField("8"));
- panel.add(createLabel("\"min!\""));
- panel.add(createTextField("3", 3), "width min!");
- panel.add(createLabel("\"pref!\""));
- panel.add(createTextField("3", 3), "width pref!");
- panel.add(createLabel("\"min:pref\""));
- panel.add(createTextField("8", 8), "width min:pref");
- panel.add(createLabel("\"min:100:150\""));
- panel.add(createTextField("8", 8), "width min:100:150");
- panel.add(createLabel("\"min:100:150, growx\""));
- panel.add(createTextField("8", 8), "width min:100:150, growx");
- panel.add(createLabel("\"min:100, growx\""));
- panel.add(createTextField("8", 8), "width min:100, growx");
- panel.add(createLabel("\"40!\""));
- panel.add(createTextField("8", 8), "width 40!");
- panel.add(createLabel("\"40:40:40\""));
- panel.add(createTextField("8", 8), "width 40:40:40");
-
- tabbedPane.addTab("Component Sizes", splitPane);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "MigLayout LM = new MigLayout(\"wrap\", \"[right][0:pref,grow]\", \"\");\n" +
- "\n" +
- "JPanel panel = createTabPanel(LM);\n" +
- "JScrollPane descrText = createTextAreaScroll(\"Use slider to see how the components grow and shrink depending on the constraints set on them.\", 0, 0, false);\n" +
- "\n" +
- "descrText.setOpaque(OPAQUE);\n" +
- "descrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" +
- "((JTextArea) descrText.getViewport().getView()).setOpaque(OPAQUE);\n" +
- "descrText.getViewport().setOpaque(OPAQUE);\n" +
- "\n" +
- "JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panel, descrText);\n" +
- "splitPane.setOpaque(OPAQUE);\n" +
- "splitPane.setBorder(null);\n" +
- "\n" +
- "panel.add(createLabel(\"\\\"\\\"\"));\n" +
- "panel.add(createTextField(\"8\", 8));\n" +
- "panel.add(createLabel(\"\\\"min!\\\"\"));\n" +
- "panel.add(createTextField(\"3\", 3), \"width min!\");\n" +
- "panel.add(createLabel(\"\\\"pref!\\\"\"));\n" +
- "panel.add(createTextField(\"3\", 3), \"width pref!\");\n" +
- "panel.add(createLabel(\"\\\"min:pref\\\"\"));\n" +
- "panel.add(createTextField(\"8\", 8), \"width min:pref\");\n" +
- "panel.add(createLabel(\"\\\"min:100:150\\\"\"));\n" +
- "panel.add(createTextField(\"8\", 8), \"width min:100:150\");\n" +
- "panel.add(createLabel(\"\\\"min:100:150, growx\\\"\"));\n" +
- "panel.add(createTextField(\"8\", 8), \"width min:100:150, growx\");\n" +
- "panel.add(createLabel(\"\\\"min:100, growx\\\"\"));\n" +
- "panel.add(createTextField(\"8\", 8), \"width min:100, growx\");\n" +
- "panel.add(createLabel(\"\\\"40!\\\"\"));\n" +
- "panel.add(createTextField(\"8\", 8), \"width 40!\");\n" +
- "panel.add(createLabel(\"\\\"40:40:40\\\"\"));\n" +
- "panel.add(createTextField(\"8\", 8), \"width 40:40:40\");\n" +
- "\n" +
- "tabbedPane.addTab(\"Component Sizes\", splitPane);");
-
- return tabbedPane;
- }
-
- public JComponent createCell_Alignments()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // Horizontal
- MigLayout hLM = new MigLayout("wrap",
- "[grow,left][grow,center][grow,right][grow,fill,center]",
- "[]unrel[][]");
- JPanel hPanel = createTabPanel(hLM);
- String[] sizes = new String[] {"", "growx", "growx 0", "left", "center", "right", "leading", "trailing"};
- hPanel.add(createLabel("[left]"), "c");
- hPanel.add(createLabel("[center]"), "c");
- hPanel.add(createLabel("[right]"), "c");
- hPanel.add(createLabel("[fill,center]"), "c, growx 0");
-
- for (int r = 0; r < sizes.length; r++) {
- for (int c = 0; c < 4; c++) {
- String text = sizes[r].length() > 0 ? sizes[r] : "default";
- hPanel.add(createButton(text), sizes[r]);
- }
- }
-
- // Vertical
- MigLayout vLM = new MigLayout("wrap,flowy",
- "[right][]",
- "[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]");
- JPanel vPanel = createTabPanel(vLM);
- String[] vSizes = new String[] {"", "growy", "growy 0", "top", "center", "bottom"};
- vPanel.add(createLabel("[top]"), "center");
- vPanel.add(createLabel("[center]"), "center");
- vPanel.add(createLabel("[bottom]"), "center");
- vPanel.add(createLabel("[fill, bottom]"), "center, growy 0");
- vPanel.add(createLabel("[fill, baseline]"), "center");
-
- for (int c = 0; c < vSizes.length; c++) {
- for (int r = 0; r < 5; r++) {
- String text = vSizes[c].length() > 0 ? vSizes[c] : "default";
- JButton b = createButton(text);
- if (r == 4 && c <= 1)
- b.setFont(new Font("sansserif", Font.PLAIN, 16 + c * 5));
- vPanel.add(b, vSizes[c]);
- }
- }
-
- tabbedPane.addTab("Horizontal", hPanel);
- tabbedPane.addTab("Vertical", vPanel);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// Horizontal\n" +
- "MigLayout hLM = new MigLayout(\"wrap\",\n" +
- " \"[grow,left][grow,center][grow,right][grow,fill,center]\",\n" +
- " \"[]unrel[][]\");\n" +
- "JPanel hPanel = createTabPanel(hLM);\n" +
- "String[] sizes = new String[] {\"\", \"growx\", \"growx 0\", \"left\", \"center\", \"right\", \"leading\", \"trailing\"};\n" +
- "hPanel.add(createLabel(\"[left]\"), \"c\");\n" +
- "hPanel.add(createLabel(\"[center]\"), \"c\");\n" +
- "hPanel.add(createLabel(\"[right]\"), \"c\");\n" +
- "hPanel.add(createLabel(\"[fill,center]\"), \"c, growx 0\");\n" +
- "\n" +
- "for (int r = 0; r < sizes.length; r++) {\n" +
- "\tfor (int c = 0; c < 4; c++) {\n" +
- "\t\tString text = sizes[r].length() > 0 ? sizes[r] : \"default\";\n" +
- "\t\thPanel.add(createButton(text), sizes[r]);\n" +
- "\t}\n" +
- "}\n" +
- "\n" +
- "// Vertical\n" +
- "MigLayout vLM = new MigLayout(\"wrap,flowy\",\n" +
- " \"[right][]\",\n" +
- " \"[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]\");\n" +
- "JPanel vPanel = createTabPanel(vLM);\n" +
- "String[] vSizes = new String[] {\"\", \"growy\", \"growy 0\", \"top\", \"center\", \"bottom\"};\n" +
- "vPanel.add(createLabel(\"[top]\"), \"center\");\n" +
- "vPanel.add(createLabel(\"[center]\"), \"center\");\n" +
- "vPanel.add(createLabel(\"[bottom]\"), \"center\");\n" +
- "vPanel.add(createLabel(\"[fill, bottom]\"), \"center, growy 0\");\n" +
- "vPanel.add(createLabel(\"[fill, baseline]\"), \"center\");\n" +
- "\n" +
- "for (int c = 0; c < vSizes.length; c++) {\n" +
- "\tfor (int r = 0; r < 5; r++) {\n" +
- "\t\tString text = vSizes[c].length() > 0 ? vSizes[c] : \"default\";\n" +
- "\t\tJButton b = createButton(text);\n" +
- "\t\tif (r == 4 && c <= 1)\n" +
- "\t\t\tb.setFont(new Font(\"sansserif\", Font.PLAIN, 16 + c * 5));\n" +
- "\t\tvPanel.add(b, vSizes[c]);\n" +
- "\t}\n" +
- "}\n" +
- "\n" +
- "tabbedPane.addTab(\"Horizontal\", hPanel);\n" +
- "tabbedPane.addTab(\"Vertical\", vPanel);");
-
- return tabbedPane;
- }
-
- public JComponent createUnits()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // Horizontal
- MigLayout hLM = new MigLayout("wrap,nocache",
- "[right][]",
- "");
- JPanel hPanel = createTabPanel(hLM);
- String[] sizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "20sp"};
- for (int i = 0; i < sizes.length; i++) {
- hPanel.add(createLabel(sizes[i]));
- hPanel.add(createTextField(""), "width " + sizes[i] + "!");
- }
-
- // Horizontal lp
- MigLayout hlpLM = new MigLayout("nocache", "[right][][]", "");
- JPanel hlpPanel = createTabPanel(hlpLM);
- hlpPanel.add(createLabel("9 cols"));
- hlpPanel.add(createTextField(9));
- String[] lpSizes = new String[] {"75lp", "75px", "88px", "100px"};
- hlpPanel.add(createLabel("Width of createTextField(9)"), "wrap");
- for (int i = 0; i < lpSizes.length; i++) {
- hlpPanel.add(createLabel(lpSizes[i]));
- hlpPanel.add(createTextField(""), "width " + lpSizes[i] + "!, wrap");
- }
-
- // Vertical
- MigLayout vLM = new MigLayout("wrap,flowy,nocache",
- "[c]",
- "[top][top]");
- JPanel vPanel = createTabPanel(vLM);
- String[] vSizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "20sp"};
- for (int i = 0; i < sizes.length; i++) {
- vPanel.add(createLabel(vSizes[i]));
- vPanel.add(createTextArea("", 0, 5), "width 50!, height " + vSizes[i] + "!");
- }
-
- // Vertical lp
- MigLayout vlpLM = new MigLayout("wrap,flowy,nocache",
- "[c]",
- "[top][top]40px[top][top]");
- JPanel vlpPanel = createTabPanel(vlpLM);
- vlpPanel.add(createLabel("4 rows"));
- vlpPanel.add(createTextArea("", 4, 5), "width 50!");
- vlpPanel.add(createLabel("field"));
- vlpPanel.add(createTextField(5));
-
- String[] vlpSizes1 = new String[] {"63lp", "57px", "63px", "68px", "25%"};
- String[] vlpSizes2 = new String[] {"21lp", "21px", "23px", "24px", "10%"};
- for (int i = 0; i < vlpSizes1.length; i++) {
- vlpPanel.add(createLabel(vlpSizes1[i]));
- vlpPanel.add(createTextArea("", 1, 5), "width 50!, height " + vlpSizes1[i] + "!");
- vlpPanel.add(createLabel(vlpSizes2[i]));
- vlpPanel.add(createTextField(5), "height " + vlpSizes2[i] + "!");
- }
-
- vlpPanel.add(createLabel("button"), "skip 2");
- vlpPanel.add(createButton("..."));
-
- tabbedPane.addTab("Horizontal", hPanel);
- tabbedPane.addTab("Horizontal LP", hlpPanel);
- tabbedPane.addTab("Vertical", vPanel);
- tabbedPane.addTab("Vertical LP", vlpPanel);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// Horizontal\n" +
- "MigLayout hLM = new MigLayout(\"wrap,nocache\",\n" +
- "\t\t\t\t\t\t\t \"[right][]\",\n" +
- "\t\t\t\t\t\t\t \"\");\n" +
- "JPanel hPanel = createTabPanel(hLM);\n" +
- "String[] sizes = new String[] {\"72pt\", \"25.4mm\", \"2.54cm\", \"1in\", \"72px\", \"96px\", \"120px\", \"25%\", \"20sp\"};\n" +
- "for (int i = 0; i < sizes.length; i++) {\n" +
- "\thPanel.add(createLabel(sizes[i]));\n" +
- "\thPanel.add(createTextField(\"\"), \"width \" + sizes[i] + \"!\");\n" +
- "}\n" +
- "\n" +
- "// Horizontal lp\n" +
- "MigLayout hlpLM = new MigLayout(\"nocache\", \"[right][][]\", \"\");\n" +
- "JPanel hlpPanel = createTabPanel(hlpLM);\n" +
- "hlpPanel.add(createLabel(\"9 cols\"));\n" +
- "hlpPanel.add(createTextField(9));\n" +
- "String[] lpSizes = new String[] {\"75lp\", \"75px\", \"88px\", \"100px\"};\n" +
- "hlpPanel.add(createLabel(\"Width of createTextField(9)\"), \"wrap\");\n" +
- "for (int i = 0; i < lpSizes.length; i++) {\n" +
- "\thlpPanel.add(createLabel(lpSizes[i]));\n" +
- "\thlpPanel.add(createTextField(\"\"), \"width \" + lpSizes[i] + \"!, wrap\");\n" +
- "}\n" +
- "\n" +
- "// Vertical\n" +
- "MigLayout vLM = new MigLayout(\"wrap,flowy,nocache\",\n" +
- "\t\t\t\t\t\t\t \"[c]\",\n" +
- "\t\t\t\t\t\t\t \"[top][top]\");\n" +
- "JPanel vPanel = createTabPanel(vLM);\n" +
- "String[] vSizes = new String[] {\"72pt\", \"25.4mm\", \"2.54cm\", \"1in\", \"72px\", \"96px\", \"120px\", \"25%\", \"20sp\"};\n" +
- "for (int i = 0; i < sizes.length; i++) {\n" +
- "\tvPanel.add(createLabel(vSizes[i]));\n" +
- "\tvPanel.add(createTextArea(\"\", 0, 5), \"width 50!, height \" + vSizes[i] + \"!\");\n" +
- "}\n" +
- "\n" +
- "// Vertical lp\n" +
- "MigLayout vlpLM = new MigLayout(\"wrap,flowy,nocache\",\n" +
- "\t\t\t\t\t\t\t\t\"[c]\",\n" +
- "\t\t\t\t\t\t\t\t\"[top][top]40px[top][top]\");\n" +
- "JPanel vlpPanel = createTabPanel(vlpLM);\n" +
- "vlpPanel.add(createLabel(\"4 rows\"));\n" +
- "vlpPanel.add(createTextArea(\"\", 4, 5), \"width 50!\");\n" +
- "vlpPanel.add(createLabel(\"field\"));\n" +
- "vlpPanel.add(createTextField(5));\n" +
- "\n" +
- "String[] vlpSizes1 = new String[] {\"63lp\", \"57px\", \"63px\", \"68px\", \"25%\"};\n" +
- "String[] vlpSizes2 = new String[] {\"21lp\", \"21px\", \"23px\", \"24px\", \"10%\"};\n" +
- "for (int i = 0; i < vlpSizes1.length; i++) {\n" +
- "\tvlpPanel.add(createLabel(vlpSizes1[i]));\n" +
- "\tvlpPanel.add(createTextArea(\"\", 1, 5), \"width 50!, height \" + vlpSizes1[i] + \"!\");\n" +
- "\tvlpPanel.add(createLabel(vlpSizes2[i]));\n" +
- "\tvlpPanel.add(createTextField(5), \"height \" + vlpSizes2[i] + \"!\");\n" +
- "}\n" +
- "\n" +
- "vlpPanel.add(createLabel(\"button\"), \"skip 2\");\n" +
- "vlpPanel.add(createButton(\"...\"));\n" +
- "\n" +
- "tabbedPane.addTab(\"Horizontal\", hPanel);\n" +
- "tabbedPane.addTab(\"Horizontal LP\", hlpPanel);\n" +
- "tabbedPane.addTab(\"Vertical\", vPanel);\n" +
- "tabbedPane.addTab(\"Vertical LP\", vlpPanel);");
-
- return tabbedPane;
- }
-
- public JComponent createGrouping()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // Ungrouped
- MigLayout ugM = new MigLayout("", "[]push[][][]", "");
- JPanel ugPanel = createTabPanel(ugM);
- ugPanel.add(createButton("Help"));
- ugPanel.add(createButton("< Back"), "");
- ugPanel.add(createButton("Forward >"), "gap push");
- ugPanel.add(createButton("Apply"), "gap unrel");
- ugPanel.add(createButton("Cancel"), "gap unrel");
-
- // Grouped Components
- MigLayout gM = new MigLayout("nogrid, fillx");
- JPanel gPanel = createTabPanel(gM);
- gPanel.add(createButton("Help"), "sg");
- gPanel.add(createButton("< Back"), "sg,gap push");
- gPanel.add(createButton("Forward >"), "sg");
- gPanel.add(createButton("Apply"), "sg,gap unrel");
- gPanel.add(createButton("Cancel"), "sg,gap unrel");
-
- // Grouped Columns
- MigLayout gcM = new MigLayout("", "[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]", "");
- JPanel gcPanel = createTabPanel(gcM);
- gcPanel.add(createButton("Help"));
- gcPanel.add(createButton("< Back"));
- gcPanel.add(createButton("Forward >"));
- gcPanel.add(createButton("Apply"));
- gcPanel.add(createButton("Cancel"));
-
- // Ungrouped Rows
- MigLayout ugrM = new MigLayout(); // no "sg" is the only difference to next panel
- JPanel ugrPanel = createTabPanel(ugrM);
- ugrPanel.add(createLabel("File Number:"));
- ugrPanel.add(createTextField(30), "wrap");
- ugrPanel.add(createLabel("BL/MBL number:"));
- ugrPanel.add(createTextField(7), "split 2");
- ugrPanel.add(createTextField(7), "wrap");
- ugrPanel.add(createLabel("Entry Date:"));
- ugrPanel.add(createTextField(7), "wrap");
- ugrPanel.add(createLabel("RFQ Number:"));
- ugrPanel.add(createTextField(30), "wrap");
- ugrPanel.add(createLabel("Goods:"));
- ugrPanel.add(createCheck("Dangerous"), "wrap");
- ugrPanel.add(createLabel("Shipper:"));
- ugrPanel.add(createTextField(30), "wrap");
- ugrPanel.add(createLabel("Customer:"));
- ugrPanel.add(createTextField(""), "split 2,growx");
- ugrPanel.add(createButton("..."), "width 60px:pref,wrap");
- ugrPanel.add(createLabel("Port of Loading:"));
- ugrPanel.add(createTextField(30), "wrap");
- ugrPanel.add(createLabel("Destination:"));
- ugrPanel.add(createTextField(30), "wrap");
-
- // Grouped Rows
- MigLayout grM = new MigLayout("", "[]", "[sg]"); // "sg" is the only difference to previous panel
- JPanel grPanel = createTabPanel(grM);
- grPanel.add(createLabel("File Number:"));
- grPanel.add(createTextField(30),"wrap");
- grPanel.add(createLabel("BL/MBL number:"));
- grPanel.add(createTextField(7),"split 2");
- grPanel.add(createTextField(7), "wrap");
- grPanel.add(createLabel("Entry Date:"));
- grPanel.add(createTextField(7), "wrap");
- grPanel.add(createLabel("RFQ Number:"));
- grPanel.add(createTextField(30), "wrap");
- grPanel.add(createLabel("Goods:"));
- grPanel.add(createCheck("Dangerous"), "wrap");
- grPanel.add(createLabel("Shipper:"));
- grPanel.add(createTextField(30), "wrap");
- grPanel.add(createLabel("Customer:"));
- grPanel.add(createTextField(""), "split 2,growx");
- grPanel.add(createButton("..."), "width 50px:pref,wrap");
- grPanel.add(createLabel("Port of Loading:"));
- grPanel.add(createTextField(30), "wrap");
- grPanel.add(createLabel("Destination:"));
- grPanel.add(createTextField(30), "wrap");
-
- tabbedPane.addTab("Ungrouped", ugPanel);
- tabbedPane.addTab("Grouped (Components)", gPanel);
- tabbedPane.addTab("Grouped (Columns)", gcPanel);
- tabbedPane.addTab("Ungrouped Rows", ugrPanel);
- tabbedPane.addTab("Grouped Rows", grPanel);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// Ungrouped\n" +
- "MigLayout ugM = new MigLayout(\"\", \"[]push[][][]\", \"\");\n" +
- "JPanel ugPanel = createTabPanel(ugM);\n" +
- "ugPanel.add(createButton(\"Help\"));\n" +
- "ugPanel.add(createButton(\"< Back\"), \"\");\n" +
- "ugPanel.add(createButton(\"Forward >\"), \"gap push\");\n" +
- "ugPanel.add(createButton(\"Apply\"), \"gap unrel\");\n" +
- "ugPanel.add(createButton(\"Cancel\"), \"gap unrel\");\n" +
- "\n" +
- "// Grouped Components\n" +
- "MigLayout gM = new MigLayout(\"nogrid, fillx\");\n" +
- "JPanel gPanel = createTabPanel(gM);\n" +
- "gPanel.add(createButton(\"Help\"), \"sg\");\n" +
- "gPanel.add(createButton(\"< Back\"), \"sg,gap push\");\n" +
- "gPanel.add(createButton(\"Forward >\"), \"sg\");\n" +
- "gPanel.add(createButton(\"Apply\"), \"sg,gap unrel\");\n" +
- "gPanel.add(createButton(\"Cancel\"), \"sg,gap unrel\");\n" +
- "\n" +
- "// Grouped Columns\n" +
- "MigLayout gcM = new MigLayout(\"\", \"[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]\", \"\");\n" +
- "JPanel gcPanel = createTabPanel(gcM);\n" +
- "gcPanel.add(createButton(\"Help\"));\n" +
- "gcPanel.add(createButton(\"< Back\"));\n" +
- "gcPanel.add(createButton(\"Forward >\"));\n" +
- "gcPanel.add(createButton(\"Apply\"));\n" +
- "gcPanel.add(createButton(\"Cancel\"));\n" +
- "\n" +
- "// Ungrouped Rows\n" +
- "MigLayout ugrM = new MigLayout(); // no \"sg\" is the only difference to next panel\n" +
- "JPanel ugrPanel = createTabPanel(ugrM);\n" +
- "ugrPanel.add(createLabel(\"File Number:\"));\n" +
- "ugrPanel.add(createTextField(30), \"wrap\");\n" +
- "ugrPanel.add(createLabel(\"BL/MBL number:\"));\n" +
- "ugrPanel.add(createTextField(7), \"split 2\");\n" +
- "ugrPanel.add(createTextField(7), \"wrap\");\n" +
- "ugrPanel.add(createLabel(\"Entry Date:\"));\n" +
- "ugrPanel.add(createTextField(7), \"wrap\");\n" +
- "ugrPanel.add(createLabel(\"RFQ Number:\"));\n" +
- "ugrPanel.add(createTextField(30), \"wrap\");\n" +
- "ugrPanel.add(createLabel(\"Goods:\"));\n" +
- "ugrPanel.add(createCheck(\"Dangerous\"), \"wrap\");\n" +
- "ugrPanel.add(createLabel(\"Shipper:\"));\n" +
- "ugrPanel.add(createTextField(30), \"wrap\");\n" +
- "ugrPanel.add(createLabel(\"Customer:\"));\n" +
- "ugrPanel.add(createTextField(\"\"), \"split 2,growx\");\n" +
- "ugrPanel.add(createButton(\"...\"), \"width 60px:pref,wrap\");\n" +
- "ugrPanel.add(createLabel(\"Port of Loading:\"));\n" +
- "ugrPanel.add(createTextField(30), \"wrap\");\n" +
- "ugrPanel.add(createLabel(\"Destination:\"));\n" +
- "ugrPanel.add(createTextField(30), \"wrap\");\n" +
- "\n" +
- "// Grouped Rows\n" +
- "MigLayout grM = new MigLayout(\"\", \"[]\", \"[sg]\"); // \"sg\" is the only difference to previous panel\n" +
- "JPanel grPanel = createTabPanel(grM);\n" +
- "grPanel.add(createLabel(\"File Number:\"));\n" +
- "grPanel.add(createTextField(30),\"wrap\");\n" +
- "grPanel.add(createLabel(\"BL/MBL number:\"));\n" +
- "grPanel.add(createTextField(7),\"split 2\");\n" +
- "grPanel.add(createTextField(7), \"wrap\");\n" +
- "grPanel.add(createLabel(\"Entry Date:\"));\n" +
- "grPanel.add(createTextField(7), \"wrap\");\n" +
- "grPanel.add(createLabel(\"RFQ Number:\"));\n" +
- "grPanel.add(createTextField(30), \"wrap\");\n" +
- "grPanel.add(createLabel(\"Goods:\"));\n" +
- "grPanel.add(createCheck(\"Dangerous\"), \"wrap\");\n" +
- "grPanel.add(createLabel(\"Shipper:\"));\n" +
- "grPanel.add(createTextField(30), \"wrap\");\n" +
- "grPanel.add(createLabel(\"Customer:\"));\n" +
- "grPanel.add(createTextField(\"\"), \"split 2,growx\");\n" +
- "grPanel.add(createButton(\"...\"), \"width 50px:pref,wrap\");\n" +
- "grPanel.add(createLabel(\"Port of Loading:\"));\n" +
- "grPanel.add(createTextField(30), \"wrap\");\n" +
- "grPanel.add(createLabel(\"Destination:\"));\n" +
- "grPanel.add(createTextField(30), \"wrap\");\n" +
- "\n" +
- "tabbedPane.addTab(\"Ungrouped\", ugPanel);\n" +
- "tabbedPane.addTab(\"Grouped (Components)\", gPanel);\n" +
- "tabbedPane.addTab(\"Grouped (Columns)\", gcPanel);\n" +
- "tabbedPane.addTab(\"Ungrouped Rows\", ugrPanel);\n" +
- "tabbedPane.addTab(\"Grouped Rows\", grPanel);");
-
- return tabbedPane;
- }
-
- public JComponent createSpan()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // Horizontal span
- MigLayout colLM = new MigLayout("nocache",
- "[fill][25%!,fill][105lp!,fill][100px!,fill]",
- "[]15[][]");
- JPanel colPanel = createTabPanel(colLM);
- colPanel.add(createTextField("Col1 [ ]"));
- colPanel.add(createTextField("Col2 [25%!]"));
- colPanel.add(createTextField("Col3 [105lp!]"));
- colPanel.add(createTextField("Col4 [100px!]"), "wrap");
-
- colPanel.add(createLabel("Full Name:"));
- colPanel.add(createTextField("span, growx", 40), "span,growx");
-
- colPanel.add(createLabel("Phone:"));
- colPanel.add(createTextField(5), "span 3, split 5");
- colPanel.add(createTextField(7));
- colPanel.add(createTextField(7));
- colPanel.add(createTextField(9));
- colPanel.add(createLabel("(span 3, split 4)"), "wrap");
-
- colPanel.add(createLabel("Zip/City:"));
- colPanel.add(createTextField(5));
- colPanel.add(createTextField("span 2, growx", 5), "span 2,growx");
-
- // Vertical span
- MigLayout rowLM = new MigLayout("wrap",
- "[225lp]para[225lp]",
- "[]3[]unrel[]3[]unrel[]3[]");
- JPanel rowPanel = createTabPanel(rowLM);
- rowPanel.add(createLabel("Name"));
- rowPanel.add(createLabel("Notes"));
- rowPanel.add(createTextField("growx"), "growx");
- rowPanel.add(createTextArea("spany,grow", 5, 20), "spany,grow");
- rowPanel.add(createLabel("Phone"));
- rowPanel.add(createTextField("growx"), "growx");
- rowPanel.add(createLabel("Fax"));
- rowPanel.add(createTextField("growx"), "growx");
-
- tabbedPane.addTab("Column Span/Split", colPanel);
- tabbedPane.addTab("Row Span", rowPanel);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("\t\tJTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "\t\t// Horizontal span\n" +
- "\t\tMigLayout colLM = new MigLayout(\"\",\n" +
- "\t\t \"[fill][25%!,fill][105lp!,fill][100px!,fill]\",\n" +
- "\t\t \"[]15[][]\");\n" +
- "\t\tJPanel colPanel = createTabPanel(colLM);\n" +
- "\t\tcolPanel.add(createTextField(\"Col1 [ ]\"));\n" +
- "\t\tcolPanel.add(createTextField(\"Col2 [25%!]\"));\n" +
- "\t\tcolPanel.add(createTextField(\"Col3 [105lp!]\"));\n" +
- "\t\tcolPanel.add(createTextField(\"Col4 [100px!]\"), \"wrap\");\n" +
- "\n" +
- "\t\tcolPanel.add(createLabel(\"Full Name:\"));\n" +
- "\t\tcolPanel.add(createTextField(\"span, growx\", 40), \"span,growx\");\n" +
- "\n" +
- "\t\tcolPanel.add(createLabel(\"Phone:\"));\n" +
- "\t\tcolPanel.add(createTextField(5), \"span 3, split 5\");\n" +
- "\t\tcolPanel.add(createTextField(7));\n" +
- "\t\tcolPanel.add(createTextField(7));\n" +
- "\t\tcolPanel.add(createTextField(9));\n" +
- "\t\tcolPanel.add(createLabel(\"(span 3, split 4)\"), \"wrap\");\n" +
- "\n" +
- "\t\tcolPanel.add(createLabel(\"Zip/City:\"));\n" +
- "\t\tcolPanel.add(createTextField(5));\n" +
- "\t\tcolPanel.add(createTextField(\"span 2, growx\", 5), \"span 2,growx\");\n" +
- "\n" +
- "\t\t// Vertical span\n" +
- "\t\tMigLayout rowLM = new MigLayout(\"wrap\",\n" +
- "\t\t \"[225lp]para[225lp]\",\n" +
- "\t\t \"[]3[]unrel[]3[]unrel[]3[]\");\n" +
- "\t\tJPanel rowPanel = createTabPanel(rowLM);\n" +
- "\t\trowPanel.add(createLabel(\"Name\"));\n" +
- "\t\trowPanel.add(createLabel(\"Notes\"));\n" +
- "\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" +
- "\t\trowPanel.add(createTextArea(\"spany,grow\", 5, 20), \"spany,grow\");\n" +
- "\t\trowPanel.add(createLabel(\"Phone\"));\n" +
- "\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" +
- "\t\trowPanel.add(createLabel(\"Fax\"));\n" +
- "\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" +
- "\n" +
- "\t\ttabbedPane.addTab(\"Column Span/Split\", colPanel);\n" +
- "\t\ttabbedPane.addTab(\"Row Span\", rowPanel);");
-
- return tabbedPane;
- }
-
- public JComponent createGrowing()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // All tab
- MigLayout allLM = new MigLayout("",
- "[pref!][grow,fill]",
- "[]15[]");
- JPanel allTab = createTabPanel(allLM);
- allTab.add(createLabel("Fixed"));
- allTab.add(createLabel("Gets all extra space"), "wrap");
- allTab.add(createTextField(5));
- allTab.add(createTextField(5));
-
- // Half tab
- MigLayout halfLM = new MigLayout("",
- "[pref!][grow,fill]",
- "[]15[]");
- JPanel halfTab = createTabPanel(halfLM);
- halfTab.add(createLabel("Fixed"));
- halfTab.add(createLabel("Gets half of extra space"));
- halfTab.add(createLabel("Gets half of extra space"), "wrap");
- halfTab.add(createTextField(5));
- halfTab.add(createTextField(5));
- halfTab.add(createTextField(5));
-
- // Percent 1 tab
- MigLayout p1LM = new MigLayout("",
- "[pref!][0:0,grow 25,fill][0:0,grow 75,fill]",
- "[]15[]");
- JPanel p1Tab = createTabPanel(p1LM);
- p1Tab.add(createLabel("Fixed"));
- p1Tab.add(createLabel("Gets 25% of extra space"), "");
- p1Tab.add(createLabel("Gets 75% of extra space"), "wrap");
- p1Tab.add(createTextField(5));
- p1Tab.add(createTextField(5));
- p1Tab.add(createTextField(5));
-
- // Percent 2 tab
- MigLayout p2LM = new MigLayout("",
- "[0:0,grow 33,fill][0:0,grow 67,fill]",
- "[]15[]");
- JPanel p2Tab = createTabPanel(p2LM);
- p2Tab.add(createLabel("Gets 33% of extra space"), "");
- p2Tab.add(createLabel("Gets 67% of extra space"), "wrap");
- p2Tab.add(createTextField(5));
- p2Tab.add(createTextField(5));
-
- // Vertical 1 tab
- MigLayout v1LM = new MigLayout("flowy",
- "[]15[]",
- "[][c,pref!][c,grow 25,fill][c,grow 75,fill]");
- JPanel v1Tab = createTabPanel(v1LM);
- v1Tab.add(createLabel("Fixed"), "skip");
- v1Tab.add(createLabel("Gets 25% of extra space"));
- v1Tab.add(createLabel("Gets 75% of extra space"), "wrap");
- v1Tab.add(createLabel("new JTextArea(4, 30)"));
- v1Tab.add(createTextAreaScroll("", 4, 30, false));
- v1Tab.add(createTextAreaScroll("", 4, 30, false));
- v1Tab.add(createTextAreaScroll("", 4, 30, false));
-
- // Vertical 2 tab
- MigLayout v2LM = new MigLayout("flowy",
- "[]15[]",
- "[][c,grow 33,fill][c,grow 67,fill]");
- JPanel v2Tab = createTabPanel(v2LM);
- v2Tab.add(createLabel("Gets 33% of extra space"), "skip");
- v2Tab.add(createLabel("Gets 67% of extra space"), "wrap");
- v2Tab.add(createLabel("new JTextArea(4, 30)"));
- v2Tab.add(createTextAreaScroll("", 4, 30, false));
- v2Tab.add(createTextAreaScroll("", 4, 30, false));
-
- tabbedPane.addTab("All", allTab);
- tabbedPane.addTab("Half", halfTab);
- tabbedPane.addTab("Percent 1", p1Tab);
- tabbedPane.addTab("Percent 2", p2Tab);
- tabbedPane.addTab("Vertical 1", v1Tab);
- tabbedPane.addTab("Vertical 2", v2Tab);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// All tab\n" +
- "MigLayout allLM = new MigLayout(\"\",\n" +
- " \"[pref!][grow,fill]\",\n" +
- " \"[]15[]\");\n" +
- "JPanel allTab = createTabPanel(allLM);\n" +
- "allTab.add(createLabel(\"Fixed\"));\n" +
- "allTab.add(createLabel(\"Gets all extra space\"), \"wrap\");\n" +
- "allTab.add(createTextField(5));\n" +
- "allTab.add(createTextField(5));\n" +
- "\n" +
- "// Half tab\n" +
- "MigLayout halfLM = new MigLayout(\"\",\n" +
- " \"[pref!][grow,fill]\",\n" +
- " \"[]15[]\");\n" +
- "JPanel halfTab = createTabPanel(halfLM);\n" +
- "halfTab.add(createLabel(\"Fixed\"));\n" +
- "halfTab.add(createLabel(\"Gets half of extra space\"));\n" +
- "halfTab.add(createLabel(\"Gets half of extra space\"), \"wrap\");\n" +
- "halfTab.add(createTextField(5));\n" +
- "halfTab.add(createTextField(5));\n" +
- "halfTab.add(createTextField(5));\n" +
- "\n" +
- "// Percent 1 tab\n" +
- "MigLayout p1LM = new MigLayout(\"\",\n" +
- " \"[pref!][0:0,grow 25,fill][0:0,grow 75,fill]\",\n" +
- " \"[]15[]\");\n" +
- "JPanel p1Tab = createTabPanel(p1LM);\n" +
- "p1Tab.add(createLabel(\"Fixed\"));\n" +
- "p1Tab.add(createLabel(\"Gets 25% of extra space\"), \"\");\n" +
- "p1Tab.add(createLabel(\"Gets 75% of extra space\"), \"wrap\");\n" +
- "p1Tab.add(createTextField(5));\n" +
- "p1Tab.add(createTextField(5));\n" +
- "p1Tab.add(createTextField(5));\n" +
- "\n" +
- "// Percent 2 tab\n" +
- "MigLayout p2LM = new MigLayout(\"\",\n" +
- " \"[0:0,grow 33,fill][0:0,grow 67,fill]\",\n" +
- " \"[]15[]\");\n" +
- "JPanel p2Tab = createTabPanel(p2LM);\n" +
- "p2Tab.add(createLabel(\"Gets 33% of extra space\"), \"\");\n" +
- "p2Tab.add(createLabel(\"Gets 67% of extra space\"), \"wrap\");\n" +
- "p2Tab.add(createTextField(5));\n" +
- "p2Tab.add(createTextField(5));\n" +
- "\n" +
- "// Vertical 1 tab\n" +
- "MigLayout v1LM = new MigLayout(\"flowy\",\n" +
- " \"[]15[]\",\n" +
- " \"[][c,pref!][c,grow 25,fill][c,grow 75,fill]\");\n" +
- "JPanel v1Tab = createTabPanel(v1LM);\n" +
- "v1Tab.add(createLabel(\"Fixed\"), \"skip\");\n" +
- "v1Tab.add(createLabel(\"Gets 25% of extra space\"));\n" +
- "v1Tab.add(createLabel(\"Gets 75% of extra space\"), \"wrap\");\n" +
- "v1Tab.add(createLabel(\"new JTextArea(4, 30)\"));\n" +
- "v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
- "v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
- "v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
- "\n" +
- "// Vertical 2 tab\n" +
- "MigLayout v2LM = new MigLayout(\"flowy\",\n" +
- " \"[]15[]\",\n" +
- " \"[][c,grow 33,fill][c,grow 67,fill]\");\n" +
- "JPanel v2Tab = createTabPanel(v2LM);\n" +
- "v2Tab.add(createLabel(\"Gets 33% of extra space\"), \"skip\");\n" +
- "v2Tab.add(createLabel(\"Gets 67% of extra space\"), \"wrap\");\n" +
- "v2Tab.add(createLabel(\"new JTextArea(4, 30)\"));\n" +
- "v2Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
- "v2Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" +
- "\n" +
- "tabbedPane.addTab(\"All\", allTab);\n" +
- "tabbedPane.addTab(\"Half\", halfTab);\n" +
- "tabbedPane.addTab(\"Percent 1\", p1Tab);\n" +
- "tabbedPane.addTab(\"Percent 2\", p2Tab);\n" +
- "tabbedPane.addTab(\"Vertical 1\", v1Tab);\n" +
- "tabbedPane.addTab(\"Vertical 2\", v2Tab);");
-
- return tabbedPane;
- }
-
- public JComponent createBasic_Sizes()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // Horizontal tab
- MigLayout horLM = new MigLayout("",
- "[]15[75px]25[min]25[]",
- "[]15");
- JPanel horTab = createTabPanel(horLM);
- horTab.add(createLabel("75px"), "skip");
- horTab.add(createLabel("Min"));
- horTab.add(createLabel("Pref"), "wrap");
-
- horTab.add(createLabel("new TextField(15)"));
- horTab.add(createTextField(15));
- horTab.add(createTextField(15));
- horTab.add(createTextField(15));
-
- // Vertical tab 1
- MigLayout verLM = new MigLayout("flowy,wrap",
- "[]15[]",
- "[]15[c,45px]15[c,min]15[c,pref]");
- JPanel verTab = createTabPanel(verLM);
- verTab.add(createLabel("45px"), "skip");
- verTab.add(createLabel("Min"));
- verTab.add(createLabel("Pref"));
-
- verTab.add(createLabel("new JTextArea(10, 40)"));
- verTab.add(createTextArea("", 10, 40));
- verTab.add(createTextArea("", 10, 40));
- verTab.add(createTextArea("", 10, 40));
-
- // Componentsized/Baseline 2
- MigLayout verLM2 = new MigLayout("flowy,wrap",
- "[]15[]",
- "[]15[baseline]15[baseline]15[baseline]");
- JPanel verTab2 = createTabPanel(verLM2);
- verTab2.add(createLabel("45px"), "skip");
- verTab2.add(createLabel("Min"));
- verTab2.add(createLabel("Pref"));
-
- verTab2.add(createLabel("new JTextArea(10, 40)"));
- verTab2.add(createTextArea("", 10, 40), "height 45");
- verTab2.add(createTextArea("", 10, 40), "height min");
- verTab2.add(createTextArea("", 10, 40), "height pref");
-
- tabbedPane.addTab("Horizontal - Column size set", horTab);
- tabbedPane.addTab("Vertical - Row sized", verTab);
- tabbedPane.addTab("Vertical - Component sized + Baseline", verTab2);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// Horizontal tab\n" +
- "MigLayout horLM = new MigLayout(\"\",\n" +
- " \"[]15[75px]25[min]25[]\",\n" +
- " \"[]15\");\n" +
- "JPanel horTab = createTabPanel(horLM);\n" +
- "horTab.add(createLabel(\"75px\"), \"skip\");\n" +
- "horTab.add(createLabel(\"Min\"));\n" +
- "horTab.add(createLabel(\"Pref\"), \"wrap\");\n" +
- "\n" +
- "horTab.add(createLabel(\"new TextField(15)\"));\n" +
- "horTab.add(createTextField(15));\n" +
- "horTab.add(createTextField(15));\n" +
- "horTab.add(createTextField(15));\n" +
- "\n" +
- "// Vertical tab 1\n" +
- "MigLayout verLM = new MigLayout(\"flowy,wrap\",\n" +
- " \"[]15[]\",\n" +
- " \"[]15[c,45px]15[c,min]15[c,pref]\");\n" +
- "JPanel verTab = createTabPanel(verLM);\n" +
- "verTab.add(createLabel(\"45px\"), \"skip\");\n" +
- "verTab.add(createLabel(\"Min\"));\n" +
- "verTab.add(createLabel(\"Pref\"));\n" +
- "\n" +
- "verTab.add(createLabel(\"new JTextArea(10, 40)\"));\n" +
- "verTab.add(createTextArea(\"\", 10, 40));\n" +
- "verTab.add(createTextArea(\"\", 10, 40));\n" +
- "verTab.add(createTextArea(\"\", 10, 40));\n" +
- "\n" +
- "// Componentsized/Baseline 2\n" +
- "MigLayout verLM2 = new MigLayout(\"flowy,wrap\",\n" +
- " \"[]15[]\",\n" +
- " \"[]15[baseline]15[baseline]15[baseline]\");\n" +
- "JPanel verTab2 = createTabPanel(verLM2);\n" +
- "verTab2.add(createLabel(\"45px\"), \"skip\");\n" +
- "verTab2.add(createLabel(\"Min\"));\n" +
- "verTab2.add(createLabel(\"Pref\"));\n" +
- "\n" +
- "verTab2.add(createLabel(\"new JTextArea(10, 40)\"));\n" +
- "verTab2.add(createTextArea(\"\", 10, 40), \"height 45\");\n" +
- "verTab2.add(createTextArea(\"\", 10, 40), \"height min\");\n" +
- "verTab2.add(createTextArea(\"\", 10, 40), \"height pref\");\n" +
- "\n" +
- "tabbedPane.addTab(\"Horizontal - Column size set\", horTab);\n" +
- "tabbedPane.addTab(\"Vertical - Row sized\", verTab);\n" +
- "tabbedPane.addTab(\"Vertical - Component sized + Baseline\", verTab2);");
-
- return tabbedPane;
- }
-
- public JComponent createAlignments()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // Horizontal tab
- MigLayout horLM = new MigLayout("wrap",
- "[label]15[left]15[center]15[right]15[fill]15[]",
- "[]15[]");
-
- String[] horLabels = new String[] {"[label]", "[left]", "[center]", "[right]", "[fill]", "[] (Default)"};
- JPanel horTab = createTabPanel(horLM);
- String[] horNames = new String[] {"First Name", "Phone Number", "Facsmile", "Email", "Address", "Other"};
- for (int c = 0; c < horLabels.length; c++)
- horTab.add(createLabel(horLabels[c]));
-
- for (int r = 0; r < horLabels.length; r++) {
- for (int c = 0; c < horNames.length; c++)
- horTab.add(c == 0 ? createLabel(horNames[r] + ":") : createButton(horNames[r]));
- }
-
- // Vertical tab
- MigLayout verLM = new MigLayout("wrap,flowy",
- "[]unrel[]rel[]",
- "[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]");
-
- String[] verLabels = new String[] {"[top]", "[center]", "[bottom]", "[fill]", "[fill,baseline]", "[baseline]", "[] (Default)"};
- JPanel verTab = createTabPanel(verLM);
-
- String[] verNames = benchRuns == 0 ? new String[] {"<html>One</html>", "<html>One<br>Two</html>"} : new String[] {"One", "One/Two"};
- for (int c = 0; c < verLabels.length; c++)
- verTab.add(createLabel(verLabels[c]));
-
- for (int r = 0; r < verNames.length; r++) {
- for (int c = 0; c < verLabels.length; c++)
- verTab.add(createButton(verNames[r]));
- }
-
- for (int c = 0; c < verLabels.length; c++)
- verTab.add(createTextField("JTextFied"));
-
- for (int c = 0; c < verLabels.length; c++)
- verTab.add(createTextArea("JTextArea", 1, 8));
-
- for (int c = 0; c < verLabels.length; c++)
- verTab.add(createTextArea("JTextArea\nwith two lines", 1, 10));
-
- for (int c = 0; c < verLabels.length; c++)
- verTab.add(createTextAreaScroll("Scrolling JTextArea\nwith two lines", 1, 15, true));
-
- tabbedPane.addTab("Horizontal", horTab);
- tabbedPane.addTab("Vertical", verTab);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// Horizontal tab\n" +
- "MigLayout horLM = new MigLayout(\"wrap\",\n" +
- " \"[left]15[center]15[right]15[fill]15[]\",\n" +
- " \"rel[]rel\");\n" +
- "\n" +
- "String[] horLabels = new String[] {\"[left]\", \"[center]\", \"[right]\", \"[fill]\", \"[] (Default)\"};\n" +
- "JPanel horTab = createTabPanel(horLM);\n" +
- "String[] horNames = new String[] {\"First Name\", \"Phone Number\", \"Facsmile\", \"Email\", \"Address\"};\n" +
- "for (int c = 0; c < horLabels.length; c++)\n" +
- "\thorTab.add(createLabel(horLabels[c]));\n" +
- "\n" +
- "for (int r = 0; r < horLabels.length; r++) {\n" +
- "\tfor (int c = 0; c < horNames.length; c++)\n" +
- "\t\thorTab.add(createButton(horNames[r]));\n" +
- "}\n" +
- "\n" +
- "// Vertical tab\n" +
- "MigLayout verLM = new MigLayout(\"wrap,flowy\",\n" +
- " \"[]unrel[]rel[]\",\n" +
- " \"[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]\");\n" +
- "\n" +
- "String[] verLabels = new String[] {\"[top]\", \"[center]\", \"[bottom]\", \"[fill]\", \"[fill,baseline]\", \"[baseline]\", \"[] (Default)\"};\n" +
- "JPanel verTab = createTabPanel(verLM);\n" +
- "\n" +
- "String[] verNames = new String[] {\"<html>One</html>\", \"<html>One<br>Two</html>\"};\n" +
- "for (int c = 0; c < verLabels.length; c++)\n" +
- "\tverTab.add(createLabel(verLabels[c]));\n" +
- "\n" +
- "for (int r = 0; r < verNames.length; r++) {\n" +
- "\tfor (int c = 0; c < verLabels.length; c++)\n" +
- "\t\tverTab.add(createButton(verNames[r]));\n" +
- "}\n" +
- "\n" +
- "for (int c = 0; c < verLabels.length; c++)\n" +
- "\tverTab.add(createTextField(\"JTextFied\"));\n" +
- "\n" +
- "for (int c = 0; c < verLabels.length; c++)\n" +
- "\tverTab.add(createTextArea(\"JTextArea\", 1, 8));\n" +
- "\n" +
- "for (int c = 0; c < verLabels.length; c++)\n" +
- "\tverTab.add(createTextArea(\"JTextArea\\nwith two lines\", 1, 10));\n" +
- "\n" +
- "for (int c = 0; c < verLabels.length; c++)\n" +
- "\tverTab.add(createTextAreaScroll(\"Scrolling JTextArea\\nwith two lines\", 1, 15, true));\n" +
- "\n" +
- "tabbedPane.addTab(\"Horizontal\", horTab);\n" +
- "tabbedPane.addTab(\"Vertical\", verTab);");
-
- return tabbedPane;
- }
-
- public JComponent createQuick_Start()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- JPanel p = createTabPanel(new MigLayout("inset 20"));
-
- addSeparator(p, "General");
-
- p.add(createLabel("Company"), "gap para");
- p.add(createTextField(""), "span, growx");
- p.add(createLabel("Contact"), "gap para");
- p.add(createTextField(""), "span, growx, wrap para");
-
- addSeparator(p, "Propeller");
-
- p.add(createLabel("PTI/kW"), "gap para");
- p.add(createTextField(10));
- p.add(createLabel("Power/kW"),"gap para");
- p.add(createTextField(10), "wrap");
- p.add(createLabel("R/mm"), "gap para");
- p.add(createTextField(10));
- p.add(createLabel("D/mm"), "gap para");
- p.add(createTextField(10));
-
- tabbedPane.addTab("Quick Start", p);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "JPanel p = createTabPanel(new MigLayout());\n" +
- "\n" +
- "addSeparator(p, \"General\");\n" +
- "\n" +
- "p.add(createLabel(\"Company\"), \"gap para\");\n" +
- "p.add(createTextField(\"\"), \"span, growx, wrap\");\n" +
- "p.add(createLabel(\"Contact\"), \"gap para\");\n" +
- "p.add(createTextField(\"\"), \"span, growx, wrap para\");\n" +
- "\n" +
- "addSeparator(p, \"Propeller\");\n" +
- "\n" +
- "p.add(createLabel(\"PTI/kW\"), \"gap para\");\n" +
- "p.add(createTextField(10));\n" +
- "p.add(createLabel(\"Power/kW\"),\"gap para\");\n" +
- "p.add(createTextField(10), \"wrap\");\n" +
- "p.add(createLabel(\"R/mm\"), \"gap para\");\n" +
- "p.add(createTextField(10));\n" +
- "p.add(createLabel(\"D/mm\"), \"gap para\");\n" +
- "p.add(createTextField(10));\n" +
- "\n" +
- "tabbedPane.addTab(\"Quick Start\", p);");
-
- return tabbedPane;
- }
-
- public JComponent createGrow_Shrink()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- // shrink tab
- MigLayout slm = new MigLayout("nogrid");
- JPanel sPanel = createTabPanel(slm);
-
- JScrollPane sDescrText = createTextAreaScroll("Use the slider to see how the components shrink depending on the constraints set on them.\n\n'shp' means Shrink Priority. " +
- "Lower values will be shrunk before higer ones and the default value is 100.\n\n'shrink' means Shrink Weight. " +
- "Lower values relative to other's means they will shrink less when space is scarse. " +
- "Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\n\n" +
- "The component's minimum size will always be honored.", 0, 0, true);
-
- sDescrText.setOpaque(OPAQUE);
- sDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));
- ((JTextArea) sDescrText.getViewport().getView()).setOpaque(OPAQUE);
- sDescrText.getViewport().setOpaque(OPAQUE);
-
- JSplitPane sSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sPanel, sDescrText);
- sSplitPane.setOpaque(OPAQUE);
- sSplitPane.setBorder(null);
-
- sPanel.add(createTextField("shp 110", 12), "shp 110");
- sPanel.add(createTextField("Default (100)", 12), "");
- sPanel.add(createTextField("shp 90", 12), "shp 90");
-
- sPanel.add(createTextField("shrink 25", 20), "newline,shrink 25");
- sPanel.add(createTextField("shrink 75", 20), "shrink 75");
-
- sPanel.add(createTextField("Default", 20), "newline");
- sPanel.add(createTextField("Default", 20), "");
-
- sPanel.add(createTextField("shrink 0", 40), "newline,shrink 0");
-
- sPanel.add(createTextField("shp 110", 12), "newline,shp 110");
- sPanel.add(createTextField("shp 100,shrink 25", 12), "shp 100,shrink 25");
- sPanel.add(createTextField("shp 100,shrink 75", 12), "shp 100,shrink 75");
- tabbedPane.addTab("Shrink", sSplitPane);
-
- // Grow tab
- MigLayout glm = new MigLayout("nogrid", "[grow]", "");
- JPanel gPanel = createTabPanel(glm);
-
- JScrollPane gDescrText = createTextAreaScroll("'gp' means Grow Priority. " +
- "Higher values will be grown before lower ones and the default value is 100.\n\n'grow' means Grow Weight. " +
- "Higher values relative to other's means they will grow more when space is up for takes. " +
- "Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means " +
- "components will normally not grow. \n\nNote that the buttons in the first and last row have max width set to 170 to " +
- "emphasize Grow Priority.\n\nThe component's maximum size will always be honored.", 0, 0, true);
-
- gDescrText.setOpaque(OPAQUE);
- gDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));
- ((JTextArea) gDescrText.getViewport().getView()).setOpaque(OPAQUE);
- gDescrText.getViewport().setOpaque(OPAQUE);
-
- JSplitPane gSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, gPanel, gDescrText);
- gSplitPane.setOpaque(OPAQUE);
- gSplitPane.setBorder(null);
-
- gPanel.add(createButton("gp 110,grow"), "gp 110,grow,wmax 170");
- gPanel.add(createButton("Default (100),grow"), "grow,wmax 170");
- gPanel.add(createButton("gp 90,grow"), "gp 90,grow,wmax 170");
-
- gPanel.add(createButton("Default Button"), "newline");
-
- gPanel.add(createButton("growx"), "newline,growx,wrap");
-
- gPanel.add(createButton("gp 110,grow"), "gp 110,grow,wmax 170");
- gPanel.add(createButton("gp 100,grow 25"), "gp 100,grow 25,wmax 170");
- gPanel.add(createButton("gp 100,grow 75"), "gp 100,grow 75,wmax 170");
- tabbedPane.addTab("Grow", gSplitPane);
-
- // Disregard. Just forgetting the source code text close to the source code.
- setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" +
- "\n" +
- "// shrink tab\n" +
- "MigLayout slm = new MigLayout(\"nogrid\");\n" +
- "JPanel sPanel = createTabPanel(slm);\n" +
- "\n" +
- "JScrollPane sDescrText = createTextAreaScroll(\"Use the slider to see how the components shrink depending on the constraints set on them.\\n\\n'shp' means Shrink Priority. \" +\n" +
- " \"Lower values will be shrunk before higer ones and the default value is 100.\\n\\n'shrink' means Shrink Weight. \" +\n" +
- " \"Lower values relative to other's means they will shrink less when space is scarse. \" +\n" +
- " \"Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\\n\\n\" +\n" +
- " \"The component's minimum size will always be honored.\", 0, 0, true);\n" +
- "\n" +
- "sDescrText.setOpaque(OPAQUE);\n" +
- "sDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" +
- "((JTextArea) sDescrText.getViewport().getView()).setOpaque(OPAQUE);\n" +
- "sDescrText.getViewport().setOpaque(OPAQUE);\n" +
- "\n" +
- "JSplitPane sSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sPanel, sDescrText);\n" +
- "sSplitPane.setOpaque(OPAQUE);\n" +
- "sSplitPane.setBorder(null);\n" +
- "\n" +
- "sPanel.add(createTextField(\"shp 110\", 12), \"shp 110\");\n" +
- "sPanel.add(createTextField(\"Default (100)\", 12), \"\");\n" +
- "sPanel.add(createTextField(\"shp 90\", 12), \"shp 90\");\n" +
- "\n" +
- "sPanel.add(createTextField(\"shrink 25\", 20), \"newline,shrink 25\");\n" +
- "sPanel.add(createTextField(\"shrink 75\", 20), \"shrink 75\");\n" +
- "\n" +
- "sPanel.add(createTextField(\"Default\", 20), \"newline\");\n" +
- "sPanel.add(createTextField(\"Default\", 20), \"\");\n" +
- "\n" +
- "sPanel.add(createTextField(\"shrink 0\", 40), \"newline,shrink 0\");\n" +
- "\n" +
- "sPanel.add(createTextField(\"shp 110\", 12), \"newline,shp 110\");\n" +
- "sPanel.add(createTextField(\"shp 100,shrink 25\", 12), \"shp 100,shrink 25\");\n" +
- "sPanel.add(createTextField(\"shp 100,shrink 75\", 12), \"shp 100,shrink 75\");\n" +
- "tabbedPane.addTab(\"Shrink\", sSplitPane);\n" +
- "\n" +
- "// Grow tab\n" +
- "MigLayout glm = new MigLayout(\"nogrid\", \"[grow]\", \"\");\n" +
- "JPanel gPanel = createTabPanel(glm);\n" +
- "\n" +
- "JScrollPane gDescrText = createTextAreaScroll(\"'gp' means Grow Priority. \" +\n" +
- " \"Higher values will be grown before lower ones and the default value is 100.\\n\\n'grow' means Grow Weight. \" +\n" +
- " \"Higher values relative to other's means they will grow more when space is up for takes. \" +\n" +
- " \"Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means \" +\n" +
- " \"components will normally not grow. \\n\\nNote that the buttons in the first and last row have max width set to 170 to \" +\n" +
- " \"emphasize Grow Priority.\\n\\nThe component's maximum size will always be honored.\", 0, 0, true);\n" +
- "\n" +
- "gDescrText.setOpaque(OPAQUE);\n" +
- "gDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" +
- "((JTextArea) gDescrText.getViewport().getView()).setOpaque(OPAQUE);\n" +
- "gDescrText.getViewport().setOpaque(OPAQUE);\n" +
- "\n" +
- "JSplitPane gSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, gPanel, gDescrText);\n" +
- "gSplitPane.setOpaque(OPAQUE);\n" +
- "gSplitPane.setBorder(null);\n" +
- "\n" +
- "gPanel.add(createButton(\"gp 110,grow\"), \"gp 110,grow,wmax 170\");\n" +
- "gPanel.add(createButton(\"Default (100),grow\"), \"grow,wmax 170\");\n" +
- "gPanel.add(createButton(\"gp 90,grow\"), \"gp 90,grow,wmax 170\");\n" +
- "\n" +
- "gPanel.add(createButton(\"Default Button\"), \"newline\");\n" +
- "\n" +
- "gPanel.add(createButton(\"growx\"), \"newline,growx,wrap\");\n" +
- "\n" +
- "gPanel.add(createButton(\"gp 110,grow\"), \"gp 110,grow,wmax 170\");\n" +
- "gPanel.add(createButton(\"gp 100,grow 25\"), \"gp 100,grow 25,wmax 170\");\n" +
- "gPanel.add(createButton(\"gp 100,grow 75\"), \"gp 100,grow 75,wmax 170\");\n" +
- "tabbedPane.addTab(\"Grow\", gSplitPane);");
-
- return tabbedPane;
- }
-
- public JComponent createPlainApi()
- {
- JTabbedPane tabbedPane = new JTabbedPane();
-
- MigLayout lm = new MigLayout(new LC(), null, null);
- JPanel panel = createTabPanel(lm);
-
- addSeparator(panel, "Manufacturer");
- panel.add(createLabel("Company"));
- panel.add(createTextField(""), "span,growx");
- panel.add(createLabel("Contact"));
- panel.add(createTextField(""), "span,growx");
- panel.add(createLabel("Order No"));
- panel.add(createTextField(15), "wrap");
-
- addSeparator(panel, "Inspector");
- panel.add(createLabel("Name"));
- panel.add(createTextField(""), "span,growx");
- panel.add(createLabel("Reference No"));
- panel.add(createTextField(""), "wrap");
- panel.add(createLabel("Status"));
- panel.add(createCombo(new String[] {"In Progress", "Finnished", "Released"}), "wrap");
-
- addSeparator(panel, "Ship");
- panel.add(createLabel("Shipyard"));
- panel.add(createTextField(""), "span,growx");
- panel.add(createLabel("Register No"));
- panel.add(createTextField(""));
- panel.add(createLabel("Hull No"), "right");
- panel.add(createTextField(15), "wrap");
- panel.add(createLabel("Project Type"));
- panel.add(createCombo(new String[] {"New Building", "Convention", "Repair"}));
-
- tabbedPane.addTab("Plain", panel);
-
- return tabbedPane;
- }
-
- // **********************************************************
- // * Helper Methods
- // **********************************************************
-
- private final ToolTipListener toolTipListener = new ToolTipListener();
- private final ConstraintListener constraintListener = new ConstraintListener();
-
- private JLabel createLabel(String text)
- {
- return createLabel(text, SwingConstants.LEADING);
- }
-
- private JLabel createLabel(String text, int align)
- {
- final JLabel b = new JLabel(text, align);
- configureActiveComponet(b);
- return b;
- }
-
- public JComboBox createCombo(String[] items)
- {
- JComboBox combo = new JComboBox(items);
-
- if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.MAC_OSX)
- combo.setOpaque(false);
-
- return combo;
- }
-
- private JTextField createTextField(int cols)
- {
- return createTextField("", cols);
- }
-
- private JTextField createTextField(String text)
- {
- return createTextField(text, 0);
- }
-
- private JTextField createTextField(String text, int cols)
- {
- final JTextField b = new JTextField(text, cols);
-
- configureActiveComponet(b);
-
- return b;
- }
-
- private static final Font BUTT_FONT = new Font("monospaced", Font.PLAIN, 12);
- private JButton createButton()
- {
- return createButton("");
- }
-
- private JButton createButton(String text)
- {
- return createButton(text, false);
- }
-
- private JButton createButton(String text, boolean bold)
- {
- JButton b = new JButton(text) {
- public void addNotify()
- {
- super.addNotify();
- if (benchRuns == 0) { // Since this does not exist in the SWT version
- if (getText().length() == 0) {
- String lText = (String) ((MigLayout) getParent().getLayout()).getComponentConstraints(this);
- setText(lText != null && lText.length() > 0 ? lText : "<Empty>");
- }
- } else {
- setText("Benchmark Version");
- }
- }
- };
-
- if (bold)
- b.setFont(b.getFont().deriveFont(Font.BOLD));
-
- configureActiveComponet(b);
-
- b.setOpaque(buttonOpaque); // Or window's buttons will have strange border
-
- if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.MAC_OSX)
- b.setContentAreaFilled(false);
-
- return b;
- }
-
- private JToggleButton createToggleButton(String text)
- {
- JToggleButton b = new JToggleButton(text);
-// configureActiveComponet(b);
- b.setOpaque(buttonOpaque); // Or window's buttons will have strange border
- return b;
- }
-
- private JCheckBox createCheck(String text)
- {
- JCheckBox b = new JCheckBox(text);
-
- configureActiveComponet(b);
-
- b.setOpaque(OPAQUE); // Or window's checkboxes will have strange border
- return b;
- }
-
- private JPanel createTabPanel(LayoutManager lm)
- {
- JPanel panel = new JPanel(lm);
- configureActiveComponet(panel);
- panel.setOpaque(OPAQUE);
- return panel;
- }
-
- private JComponent createPanel()
- {
- return createPanel("");
- }
-
- private JComponent createPanel(String s)
- {
- JLabel panel = new JLabel(s, SwingConstants.CENTER) {
- public void addNotify()
- {
- super.addNotify();
- if (benchRuns == 0) { // Since this does not exist in the SWT version
- if (getText().length() == 0) {
- String lText = (String) ((MigLayout) getParent().getLayout()).getComponentConstraints(this);
- setText(lText != null && lText.length() > 0 ? lText : "<Empty>");
- }
- }
- }
- };
- panel.setBorder(new EtchedBorder());
- panel.setOpaque(true);
- configureActiveComponet(panel);
-
- return panel;
- }
-
- private JTextArea createTextArea(String text, int rows, int cols)
- {
- JTextArea ta = new JTextArea(text, rows, cols);
- ta.setBorder(UIManager.getBorder("TextField.border"));
- ta.setFont(UIManager.getFont("TextField.font"));
- ta.setWrapStyleWord(true);
- ta.setLineWrap(true);
-
- configureActiveComponet(ta);
-
- return ta;
- }
-
- private JScrollPane createTextAreaScroll(String text, int rows, int cols, boolean hasVerScroll)
- {
- JTextArea ta = new JTextArea(text, rows, cols);
- ta.setFont(UIManager.getFont("TextField.font"));
- ta.setWrapStyleWord(true);
- ta.setLineWrap(true);
-
- JScrollPane scroll = new JScrollPane(
- ta,
- hasVerScroll ? ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED : ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
- ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
-
- return scroll;
- }
-
- private JComponent configureActiveComponet(JComponent c)
- {
- if (benchRuns == 0) {
- c.addMouseMotionListener(toolTipListener);
- c.addMouseListener(constraintListener);
- }
- return c;
- }
-
- static final Color LABEL_COLOR = new Color(0, 70, 213);
- private void addSeparator(JPanel panel, String text)
- {
- JLabel l = createLabel(text);
- l.setForeground(LABEL_COLOR);
-
- panel.add(l, "gapbottom 1, span, split 2");
- panel.add(configureActiveComponet(new JSeparator()), "gapleft rel, growx");
- }
-
- private class ConstraintListener extends MouseAdapter
- {
- public void mousePressed(MouseEvent e)
- {
- if (e.isPopupTrigger())
- react(e);
- }
-
- public void mouseReleased(MouseEvent e)
- {
- if (e.isPopupTrigger())
- react(e);
- }
-
- public void react(MouseEvent e)
- {
- JComponent c = (JComponent) e.getSource();
- LayoutManager lm = c.getParent().getLayout();
- if (lm instanceof MigLayout == false)
- lm = c.getLayout();
-
- if (lm instanceof MigLayout) {
- MigLayout layout = (MigLayout) lm;
- boolean isComp = layout.isManagingComponent(c);
-
- Object compConstr = isComp ? layout.getComponentConstraints(c) : null;
- if (isComp && compConstr == null)
- compConstr = "";
-
- Object rowsConstr = isComp ? null : layout.getRowConstraints();
- Object colsConstr = isComp ? null : layout.getColumnConstraints();
- Object layoutConstr = isComp ? null : layout.getLayoutConstraints();
-
- ConstraintsDialog cDlg = new ConstraintsDialog(SwingDemo.this,
- layoutConstr instanceof LC ? IDEUtil.getConstraintString((LC) layoutConstr, false) : (String) layoutConstr,
- rowsConstr instanceof AC ? IDEUtil.getConstraintString((AC) rowsConstr, false, false) : (String) rowsConstr,
- colsConstr instanceof AC ? IDEUtil.getConstraintString((AC) colsConstr, false, false) : (String) colsConstr,
- compConstr instanceof CC ? IDEUtil.getConstraintString((CC) colsConstr, false) : (String) compConstr);
-
- cDlg.pack();
- cDlg.setLocationRelativeTo(c);
-
- if (cDlg.showDialog()) {
- try {
- if (isComp) {
- String constrStr = cDlg.componentConstrTF.getText().trim();
- layout.setComponentConstraints(c, constrStr);
- if (c instanceof JButton) {
- c.setFont(BUTT_FONT);
- ((JButton) c).setText(constrStr.length() == 0 ? "<Empty>" : constrStr);
- }
- } else {
- layout.setLayoutConstraints(cDlg.layoutConstrTF.getText());
- layout.setRowConstraints(cDlg.rowsConstrTF.getText());
- layout.setColumnConstraints(cDlg.colsConstrTF.getText());
- }
- } catch(Exception ex) {
- StringWriter sw = new StringWriter();
- ex.printStackTrace(new PrintWriter(sw));
- JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(c), sw.toString(), "Error parsing Constraint!", JOptionPane.ERROR_MESSAGE);
- return;
- }
-
- c.invalidate();
- c.getParent().validate();
- }
- }
- }
- }
-
- private static class ToolTipListener extends MouseMotionAdapter
- {
- public void mouseMoved(MouseEvent e)
- {
- JComponent c = (JComponent) e.getSource();
- LayoutManager lm = c.getParent().getLayout();
- if (lm instanceof MigLayout) {
- String constr = (String) ((MigLayout) lm).getComponentConstraints(c);
- c.setToolTipText((constr != null ? ("\"" + constr + "\"") : "null"));
- }
- }
- }
-
- private static class ConstraintsDialog extends JDialog implements ActionListener, KeyEventDispatcher
- {
- private static final Color ERROR_COLOR = new Color(255, 180, 180);
- private final JPanel mainPanel = new JPanel(new MigLayout("fillx,flowy,ins dialog",
- "[fill]",
- "2[]2"));
- final JTextField layoutConstrTF;
- final JTextField rowsConstrTF;
- final JTextField colsConstrTF;
- final JTextField componentConstrTF;
-
- private final JButton okButt = new JButton("OK");
- private final JButton cancelButt = new JButton("Cancel");
-
- private boolean okPressed = false;
-
- public ConstraintsDialog(Frame owner, String layoutConstr, String rowsConstr, String colsConstr, String compConstr)
- {
- super(owner, (compConstr != null ? "Edit Component Constraints" : "Edit Container Constraints"), true);
-
- layoutConstrTF = createConstraintField(layoutConstr);
- rowsConstrTF = createConstraintField(rowsConstr);
- colsConstrTF = createConstraintField(colsConstr);
- componentConstrTF = createConstraintField(compConstr);
-
- if (componentConstrTF != null) {
- mainPanel.add(new JLabel("Component Constraints"));
- mainPanel.add(componentConstrTF);
- }
-
- if (layoutConstrTF != null) {
- mainPanel.add(new JLabel("Layout Constraints"));
- mainPanel.add(layoutConstrTF);
- }
-
- if (colsConstrTF != null) {
- mainPanel.add(new JLabel("Column Constraints"), "gaptop unrel");
- mainPanel.add(colsConstrTF);
- }
-
- if (rowsConstrTF != null) {
- mainPanel.add(new JLabel("Row Constraints"), "gaptop unrel");
- mainPanel.add(rowsConstrTF);
- }
-
- mainPanel.add(okButt, "tag ok,split,flowx,gaptop 15");
- mainPanel.add(cancelButt, "tag cancel,gaptop 15");
-
- setContentPane(mainPanel);
-
- okButt.addActionListener(this);
- cancelButt.addActionListener(this);
- }
-
- public void addNotify()
- {
- super.addNotify();
- KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
- }
-
- public void removeNotify()
- {
- KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this);
- super.removeNotify();
- }
-
- public boolean dispatchKeyEvent(KeyEvent e)
- {
- if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
- dispose();
- return false;
- }
-
- public void actionPerformed(ActionEvent e)
- {
- if (e.getSource() == okButt)
- okPressed = true;
- dispose();
- }
-
- private JTextField createConstraintField(String text)
- {
- if (text == null)
- return null;
-
- final JTextField tf = new JTextField(text, 50);
- tf.setFont(new Font("monospaced", Font.PLAIN, 12));
-
- tf.addKeyListener(new KeyAdapter() {
- public void keyPressed(KeyEvent e)
- {
- if (e.getKeyCode() == KeyEvent.VK_ENTER) {
- okButt.doClick();
- return;
- }
-
- javax.swing.Timer timer = new Timer(50, new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- String constr = tf.getText();
- try {
- if (tf == layoutConstrTF) {
- ConstraintParser.parseLayoutConstraint(constr);
- } else if (tf == rowsConstrTF) {
- ConstraintParser.parseRowConstraints(constr);
- } else if (tf == colsConstrTF) {
- ConstraintParser.parseColumnConstraints(constr);
- } else if (tf == componentConstrTF) {
- ConstraintParser.parseComponentConstraint(constr);
- }
-
- tf.setBackground(Color.WHITE);
- okButt.setEnabled(true);
- } catch(Exception ex) {
- tf.setBackground(ERROR_COLOR);
- okButt.setEnabled(false);
- }
- }
- });
- timer.setRepeats(false);
- timer.start();
- }
- });
-
- return tf;
- }
-
- private boolean showDialog()
- {
- setVisible(true);
- return okPressed;
- }
- }
-
+package net.miginfocom.demo; + +import net.miginfocom.layout.*; +import net.miginfocom.swing.MigLayout; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import javax.swing.border.EtchedBorder; +import javax.swing.border.LineBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.*; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Random; + +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ +public class SwingDemo extends JFrame +{ + public static final int INITIAL_INDEX = 0; + private static final boolean DEBUG = false; + private static final boolean OPAQUE = false; + + private static final String[][] panels = new String[][] { +// {"Test", "Test, disregard"}, + {"Welcome", "\n\n \"MigLayout makes complex layouts easy and normal layouts one-liners.\""}, + {"Quick Start", "This is an example of how to build a common dialog type. Note that there are no special components, nested panels or absolute references to cell positions. If you look at the source code you will see that the layout code is very simple to understand."}, + {"Plain", "A simple example on how simple it is to create normal forms. No builders needed since the whole layout manager works like a builder."}, + {"Alignments", "Shows how the alignment of components are specified. At the top/left is the alignment for the column/row. The components have no alignments specified.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."}, + {"Cell Alignments", "Shows how components are aligned when both column/row alignments and component constraints are specified. At the top/left are the alignment for the column/row and the text on the buttons is the component constraint that will override the column/row alignment if it is an alignment.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."}, + {"Basic Sizes", "A simple example that shows how to use the column or row min/preferred/max size to set the sizes of the contained components and also an example that shows how to do this directly in the component constraints."}, + {"Growing", "A simple example that shows how to use the growx and growy constraint to set the sizes and how they should grow to fit the available size. Both the column/row and the component grow/shrink constraints can be set, but the components will always be confined to the space given by its column/row."}, + {"Grow Shrink", "Demonstrates the very flexible grow and shrink constraints that can be set on a component.\nComponents can be divided into grow/shrink groups and also have grow/shrink weight within each of those groups.\n\nBy default " + + "components shrink to their inherent (or specified) minimum size, but they don't grow."}, + {"Span", "This example shows the powerful spanning and splitting that can be specified in the component constraints. With spanning any number of cells can be merged with the additional option to split that space for more than one component. This makes layouts very flexible and reduces the number of times you will need nested panels to very few."}, + {"Flow Direction", "Shows the different flow directions. Flow direction for the layout specifies if the next cell will be in the x or y dimension. Note that it can be a different flow direction in the slit cell (the middle cell is slit in two). Wrap is set to 3 for all panels."}, + {"Grouping", "Sizes for both components and columns/rows can be grouped so they get the same size. For instance buttons in a button bar can be given a size-group so that they will all get " + + "the same minimum and preferred size (the largest within the group). Size-groups can be set for the width, height or both."}, + {"Units", "Demonstrates the basic units that are understood by MigLayout. These units can be extended by the user by adding one or more UnitConverter(s)."}, + {"Component Sizes", "Minimum, preferred and maximum component sizes can be overridden in the component constraints using any unit type. The format to do this is short and simple to understand. You simply specify the " + + "min, preferred and max sizes with a colon between.\n\nAbove are some examples of this. An exclamation mark means that the value will be used for all sizes."}, + {"Bound Sizes", "Shows how to create columns that are stable between tabs using minimum sizes."}, + {"Cell Position", "Even though MigLayout has automatic grid flow you can still specify the cell position explicitly. You can even combine absolute (x, y) and flow (skip, wrap and newline) constraints to build your layout."}, + {"Orientation", "MigLayout supports not only right-to-left orientation, but also bottom-to-top. You can even set the flow direction so that the flow is vertical instead of horizontal. It will automatically " + + "pick up if right-to-left is to be used depending on the ComponentWrapper, but it can also be manually set for every layout."}, + {"Absolute Position", "Demonstrates the option to place any number of components using absolute coordinates. This can be just the position (if min/preferred size) using \"x y p p\" format or" + + "the bounds using the \"x1 y1 x2 y2\" format. Any unit can be used and percent is relative to the parent.\nAbsolute components will not disturb the flow or occupy cells in the grid. " + + "Absolute positioned components will be taken into account when calculating the container's preferred size."}, + {"Component Links", "Components can be linked to any side of any other component. It can be a forward, backward or cyclic link references, as long as it is stable and won't continue to change value over many iterations." + + "Links are referencing the ID of another component. The ID can be overridden by the component's constrains or is provided by the ComponentWrapper. For instance it will use the component's 'name' on Swing.\n" + + "Since the links can be combined with any expression (such as 'butt1.x+10' or 'max(button.x, 200)' the links are very customizable."}, + {"Docking", "Docking components can be added around the grid. The docked component will get the whole width/height on the docked side by default, however this can be overridden. When all docked components are laid out, whatever space " + + "is left will be available for the normal grid laid out components. Docked components does not in any way affect the flow in the grid.\n\nSince the docking runs in the same code path " + + "as the normal layout code the same properties can be specified for the docking components. You can for instance set the sizes and alignment or link other components to their docked component's bounds."}, + {"Button Bars", "Button order is very customizable and are by default different on the supported platforms. E.g. Gaps, button order and minimum button size are properties that are 'per platform'. MigLayout picks up the current platform automatically and adjusts the button order and minimum button size accordingly, all without using a button builder or any other special code construct."}, + {"Visual Bounds", "Human perceptible bounds may not be the same as the mathematical bounds for the component. This is for instance the case if there is a drop shadow painted by the component's border. MigLayout can compensate " + + "for this in a simple way. Note the top middle tab-component, it is not aligned visually correct on Windows XP. For the second tab the bounds are corrected automatically on Windows XP."}, + {"Debug", "Demonstrates the non-intrusive way to get visual debugging aid. There is no need to use a special DebugPanel or anything that will need code changes. The user can simply turn on debug on the layout manager by using the \"debug\" constraint and it will " + + "continuously repaint the panel with debug information on top. This means you don't have to change your code to debug!"}, + {"Layout Showdown", "This is an implementation of the Layout Showdown posted on java.net by John O'Conner. The first tab is a pure implemenetation of the showdown that follows all the rules. The second tab is a slightly fixed version that follows some improved layout guidelines." + + "The source code is for bothe the first and for the fixed version. Note the simplification of the code for the fixed version. Writing better layouts with MiG Layout is reasier that writing bad.\n\nReference: http://weblogs.java.net/blog/joconner/archive/2006/10/more_informatio.html"}, + {"API Constraints1", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."}, + {"API Constraints2", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."} + }; + + private int lastIndex = -10; + + private JPanel contentPanel = DEBUG ? new JPanel(new BorderLayout()) : new JPanel(new MigLayout("wrap", "[]unrel[grow]", "[grow][pref]")); + + private JTabbedPane layoutPickerTabPane = new JTabbedPane(); + private JList pickerList = new JList(new DefaultListModel()); + + private JTabbedPane southTabPane = new JTabbedPane(); + private JScrollPane descrTextAreaScroll = createTextAreaScroll("", 5, 80, true); + private JTextArea descrTextArea = (JTextArea) descrTextAreaScroll.getViewport().getView(); + + private JScrollPane sourceTextAreaScroll = null; + private JTextArea sourceTextArea = null; + + private JPanel layoutDisplayPanel = new JPanel(new BorderLayout(0, 0)); + private static boolean buttonOpaque = true; + private JFrame sourceFrame = null; + private JTextArea sourceFrameTextArea = null; + + private static int benchRuns = 0; + private static long startupMillis = 0; + private static long timeToShowMillis = 0; + private static long benchRunTime = 0; + private static String benchOutFileName = null; + private static boolean append = false; + private static long lastRunTimeStart = 0; + private static StringBuffer runTimeSB = null; + + public static void main(String args[]) + { + try { + System.setProperty("apple.laf.useScreenMenuBar", "true"); + System.setProperty("com.apple.mrj.application.apple.menu.about.name", "MiGLayout Swing Demo"); + } catch(Throwable ex) { + // Beacuse we did not have permissions. + } + + startupMillis = System.currentTimeMillis(); + + String laf = UIManager.getSystemLookAndFeelClassName(); + + if (args.length > 0) { + for (int i = 0; i <args.length; i++) { + String arg = args[i].trim(); + if (arg.startsWith("-laf")) { + laf = arg.substring(4); + } else if (arg.startsWith("-bench")) { + benchRuns = 10; + try { + benchRuns = Integer.parseInt(arg.substring(6)); + } catch(Exception ex) {} + } else if (arg.startsWith("-bout")) { + benchOutFileName = arg.substring(5); + } else if (arg.startsWith("-append")) { + append = true; + } else if (arg.startsWith("-verbose")) { + runTimeSB = new StringBuffer(256); + } else if (arg.equals("-steel")) { + laf = "javax.swing.plaf.metal.MetalLookAndFeel"; + System.setProperty("swing.metalTheme", "steel"); + } else if (arg.equals("-ocean")) { + laf = "javax.swing.plaf.metal.MetalLookAndFeel"; + } else { + System.out.println("Usage: [-laf[look_&_feel_class_name]] [-bench[#_of_runs]] [-bout[benchmark_results_filename]] [-append] [-steel] [-ocean]\n" + + " -laf Set the Application Look&Feel. (Look and feel must be in Classpath)\n" + + " -bench Run demo as benchmark. Run count can be appended. 10 is default.\n" + + " -bout Benchmark results output filename.\n" + + " -append Appends the result to the -bout file.\n" + + " -verbose Print the times of every run.\n" + + " -steel Sets the old Steel theme for Sun's Metal look&feel.\n" + + " -ocean Sets the Ocean theme for Sun's Metal look&feel.\n" + + "\nExamples:\n" + + " java -jar swingdemoapp.jar -bench -boutC:/bench.txt -append\n" + + " java -jar swingdemoapp.jar -ocean -bench20\n" + + " java -cp c:\\looks-2.0.4.jar;.\\swingdemoapp.jar net.miginfocom.demo.SwingDemo -lafcom.jgoodies.looks.plastic.PlasticLookAndFeel -bench20 -boutC:/bench.txt"); + System.exit(0); + } + } + } + + if (benchRuns > 0) + LayoutUtil.setDesignTime(null, true); // So that the string constraints to create the UnitValues is saved and can be recreated exactly. + +// laf = "net.sourceforge.napkinlaf.NapkinLookAndFeel"; +// laf = "javax.swing.plaf.metal.MetalLookAndFeel"; +// System.setProperty("swing.metalTheme", "steel"); +// laf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; +// laf = "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel"; +// laf = "com.jgoodies.looks.plastic.PlasticLookAndFeel"; +// laf = "com.jgoodies.looks.plastic.Plastic3DLookAndFeel"; +// laf = "com.jgoodies.looks.plastic.PlasticXPLookAndFeel"; +// laf = "com.jgoodies.looks.windows.WindowsLookAndFeel"; + + if (laf.endsWith("WindowsLookAndFeel")) + buttonOpaque = false; + + final String laff = laf; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + UIManager.setLookAndFeel(laff); + } catch (Exception ex) { + ex.printStackTrace(); + } + + SwingDemo demo = new SwingDemo(); + } + }); + } + + public SwingDemo() + { + super("MigLayout Swing Demo v2.4 - Mig Layout v" + LayoutUtil.getVersion()); + +// if (benchRuns > 0) +// RepaintManager.currentManager(this).setDoubleBufferingEnabled(false); + + if (benchRuns == 0) { + sourceTextAreaScroll = createTextAreaScroll("", 5, 80, true); + sourceTextArea = (JTextArea) sourceTextAreaScroll.getViewport().getView(); + } + + if (DEBUG) { + contentPanel.add(layoutDisplayPanel, BorderLayout.CENTER); +// contentPanel.add(layoutPickerTabPane, BorderLayout.WEST); +// contentPanel.add(descriptionTabPane, BorderLayout.SOUTH); + } else { + contentPanel.add(layoutPickerTabPane, "spany,grow"); + contentPanel.add(layoutDisplayPanel, "grow"); + contentPanel.add(southTabPane, "growx"); + } + + setContentPane(contentPanel); + + pickerList.setOpaque(OPAQUE); + ((DefaultListCellRenderer) pickerList.getCellRenderer()).setOpaque(OPAQUE); + pickerList.setSelectionForeground(new Color(0, 0, 220)); + pickerList.setBackground(null); + pickerList.setBorder(new EmptyBorder(2, 5, 0, 4)); + pickerList.setFont(pickerList.getFont().deriveFont(Font.BOLD)); + layoutPickerTabPane.addTab("Example Browser", pickerList); + + descrTextAreaScroll.setBorder(null); + descrTextAreaScroll.setOpaque(OPAQUE); + descrTextAreaScroll.getViewport().setOpaque(OPAQUE); + descrTextArea.setOpaque(OPAQUE); + descrTextArea.setEditable(false); + descrTextArea.setBorder(new EmptyBorder(0, 4, 0, 4)); + southTabPane.addTab("Description", descrTextAreaScroll); + + + if (sourceTextArea != null) { + sourceTextAreaScroll.setBorder(null); + sourceTextAreaScroll.setOpaque(OPAQUE); + sourceTextAreaScroll.getViewport().setOpaque(OPAQUE); + sourceTextAreaScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + sourceTextArea.setOpaque(OPAQUE); + sourceTextArea.setLineWrap(false); + sourceTextArea.setWrapStyleWord(false); + sourceTextArea.setEditable(false); + sourceTextArea.setBorder(new EmptyBorder(0, 4, 0, 4)); + sourceTextArea.setFont(new Font("monospaced", Font.PLAIN, 11)); + southTabPane.addTab("Source Code", sourceTextAreaScroll); + + southTabPane.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) + { + if (e.getClickCount() == 2) + showSourceInFrame(); + } + }); + } + + for (int i = 0; i < panels.length; i++) + ((DefaultListModel) pickerList.getModel()).addElement(panels[i][0]); + + try { + setSize(900, 650); + setLocationRelativeTo(null); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setVisible(true); + } catch(Throwable t) { + t.printStackTrace(); + System.exit(1); + } + + pickerList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) + { + int ix = pickerList.getSelectedIndex(); + if (ix == -1 || lastIndex == ix) + return; + + lastIndex = ix; + + String methodName = "create" + panels[ix][0].replace(' ', '_'); + layoutDisplayPanel.removeAll(); + try { + pickerList.requestFocusInWindow(); + final JComponent panel = (JComponent) SwingDemo.class.getMethod(methodName, new Class[0]).invoke(SwingDemo.this, new Object[0]); + layoutDisplayPanel.add(panel); + descrTextArea.setText(panels[ix][1]); + descrTextArea.setCaretPosition(0); + contentPanel.revalidate(); + + } catch (Exception e1) { + e1.printStackTrace(); // Should never happpen... + } + southTabPane.setSelectedIndex(0); + } + }); + + pickerList.requestFocusInWindow(); + Toolkit.getDefaultToolkit().setDynamicLayout(true); + + if (benchRuns > 0) { + doBenchmark(); + } else { + pickerList.setSelectedIndex(INITIAL_INDEX); + + KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() { + public boolean dispatchKeyEvent(KeyEvent e) + { + if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_B && (e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) > 0) { + startupMillis = System.currentTimeMillis(); + timeToShowMillis = System.currentTimeMillis() - startupMillis; + benchRuns = 1; + doBenchmark(); + return true; + } + return false; + } + }); + } + } + + private void doBenchmark() + { + Thread benchThread = new Thread() { + public void run() + { + for (int j = 0; j < benchRuns; j++) { + lastRunTimeStart = System.currentTimeMillis(); + for (int i = 0, iCnt = pickerList.getModel().getSize(); i < iCnt; i++) { + + if (benchRuns > 0 && panels[i][0].equals("Visual Bounds")) + continue; // the SWT version does not have Visual bounds... + + final int ii = i; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + pickerList.setSelectedIndex(ii); + Toolkit.getDefaultToolkit().sync(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + + Component[] comps = layoutDisplayPanel.getComponents(); + for (int cIx = 0; cIx < comps.length; cIx++) { + if (comps[cIx] instanceof JTabbedPane) { + final JTabbedPane tp = (JTabbedPane) comps[cIx]; + + for (int k = 0, kCnt = tp.getTabCount(); k < kCnt; k++) { + final int kk = k; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + tp.setSelectedIndex(kk); + Toolkit.getDefaultToolkit().sync(); + + if (timeToShowMillis == 0) + timeToShowMillis = System.currentTimeMillis() - startupMillis; + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + if (runTimeSB != null) { + runTimeSB.append("Run ").append(j).append(": "); + runTimeSB.append(System.currentTimeMillis() - lastRunTimeStart).append(" millis.\n"); + } + } + + benchRunTime = System.currentTimeMillis() - startupMillis - timeToShowMillis; + + final String message = "Java Version: " + System.getProperty("java.version") + "\n" + + "Look & Feel: " + UIManager.getLookAndFeel().getDescription() + "\n" + + "Time to Show: " + timeToShowMillis + " millis.\n" + + (runTimeSB != null ? runTimeSB.toString() : "") + + "Benchmark Run Time: " + benchRunTime + " millis.\n" + + "Average Run Time: " + (benchRunTime / benchRuns) + " millis (" + benchRuns + " runs).\n\n"; + + if (benchOutFileName == null) { + JOptionPane.showMessageDialog(SwingDemo.this, message, "Results", JOptionPane.INFORMATION_MESSAGE); + } else { + FileWriter fw = null; + try { + fw = new FileWriter(benchOutFileName, append); + fw.write(message); + } catch(IOException ex) { + ex.printStackTrace(); + } finally { + if (fw != null) + try {fw.close();} catch(IOException ex) {} + } + } + System.out.println(message); + } + }; + benchThread.start(); + } + + private void setSource(String source) + { + if (benchRuns > 0 || sourceTextArea == null) + return; + + if (source.length() > 0) { + source = source.replaceAll("\t\t", ""); + source = "DOUBLE CLICK TAB TO SHOW SOURCE IN SEPARATE WINDOW!\n===================================================\n\n" + source; + } + sourceTextArea.setText(source); + sourceTextArea.setCaretPosition(0); + + if (sourceFrame != null && sourceFrame.isVisible()) { + sourceFrameTextArea.setText(source.length() > 105 ? source.substring(105) : "No Source Code Available!"); + sourceFrameTextArea.setCaretPosition(0); + } + } + + private void showSourceInFrame() + { + if (sourceTextArea == null) + return; + + JScrollPane sourceFrameTextAreaScroll = createTextAreaScroll("", 5, 80, true); + sourceFrameTextArea = (JTextArea) sourceFrameTextAreaScroll.getViewport().getView(); + + sourceFrameTextAreaScroll.setBorder(null); + sourceFrameTextAreaScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + sourceFrameTextArea.setLineWrap(false); + sourceFrameTextArea.setWrapStyleWord(false); + sourceFrameTextArea.setEditable(false); + sourceFrameTextArea.setBorder(new EmptyBorder(10, 10, 10, 10)); + sourceFrameTextArea.setFont(new Font("monospaced", Font.PLAIN, 12)); + + String source = this.sourceTextArea.getText(); + sourceFrameTextArea.setText(source.length() > 105 ? source.substring(105) : "No Source Code Available!"); + sourceFrameTextArea.setCaretPosition(0); + + sourceFrame = new JFrame("Source Code"); + sourceFrame.getContentPane().add(sourceFrameTextAreaScroll, BorderLayout.CENTER); + sourceFrame.setSize(700, 800); + sourceFrame.setLocationRelativeTo(this); + sourceFrame.setVisible(true); + } + + public JComponent createTest() + { + JComponent pane = new JPanel(); + + pane.setLayout(new MigLayout("debug")); + + pane.add(new JLabel("Separator"), "gapbottom 1, ax r, spanx, split"); + pane.add(new JSeparator(), "gap rel, growx"); + + JLabel label = new JLabel("<html><font color=red><b>some text in label</b></font></html>"); + + + pane.add(label, "wrap"); + pane.add(new JButton("Button1")); + pane.add(new JButton("Button2")); + pane.add(new JButton("Button3")); + + return pane; + } + + public JComponent createAPI_Constraints1() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + LC layC = new LC().fill().wrap(); + AC colC = new AC().align("right", 1).fill(2, 4).grow(100, 2, 4).align("right", 3).gap("15", 2); + AC rowC = new AC().align("top", 7).gap("15!", 6).grow(100, 8); + + JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient + + // References to text fields not stored to reduce code clutter. + + JScrollPane list2 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"})); + panel.add(list2, new CC().spanY().growY().minWidth("150").gapX(null, "10")); + + panel.add(new JLabel("Last Name")); + panel.add(new JTextField()); + panel.add(new JLabel("First Name")); + panel.add(new JTextField(), new CC().wrap().alignX("right")); + panel.add(new JLabel("Phone")); + panel.add(new JTextField()); + panel.add(new JLabel("Email")); + panel.add(new JTextField()); + panel.add(new JLabel("Address 1")); + panel.add(new JTextField(), new CC().spanX().growX()); + panel.add(new JLabel("Address 2")); + panel.add(new JTextField(), new CC().spanX().growX()); + panel.add(new JLabel("City")); + panel.add(new JTextField(), new CC().wrap()); + panel.add(new JLabel("State")); + panel.add(new JTextField()); + panel.add(new JLabel("Postal Code")); + panel.add(new JTextField(10), new CC().spanX(2).growX(0)); + panel.add(new JLabel("Country")); + panel.add(new JTextField(), new CC().wrap()); + + panel.add(new JButton("New"), new CC().spanX(5).split(5).tag("other")); + panel.add(new JButton("Delete"), new CC().tag("other")); + panel.add(new JButton("Edit"), new CC().tag("other")); + panel.add(new JButton("Save"), new CC().tag("other")); + panel.add(new JButton("Cancel"), new CC().tag("cancel")); + + tabbedPane.addTab("Layout Showdown (improved)", panel); + + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "LC layC = new LC().fill().wrap();\n" + + "AC colC = new AC().align(\"right\", 1).fill(2, 4).grow(100, 2, 4).align(\"right\", 3).gap(\"15\", 2);\n" + + "AC rowC = new AC().align(\"top\", 7).gap(\"15!\", 6).grow(100, 8);\n" + + "\n" + + "JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient\n" + + "\n" + + "// References to text fields not stored to reduce code clutter.\n" + + "\n" + + "JScrollPane list2 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" + + "panel.add(list2, new CC().spanY().growY().minWidth(\"150\").gapX(null, \"10\"));\n" + + "\n" + + "panel.add(new JLabel(\"Last Name\"));\n" + + "panel.add(new JTextField());\n" + + "panel.add(new JLabel(\"First Name\"));\n" + + "panel.add(new JTextField(), new CC().wrap().alignX(\"right\"));\n" + + "panel.add(new JLabel(\"Phone\"));\n" + + "panel.add(new JTextField());\n" + + "panel.add(new JLabel(\"Email\"));\n" + + "panel.add(new JTextField());\n" + + "panel.add(new JLabel(\"Address 1\"));\n" + + "panel.add(new JTextField(), new CC().spanX().growX());\n" + + "panel.add(new JLabel(\"Address 2\"));\n" + + "panel.add(new JTextField(), new CC().spanX().growX());\n" + + "panel.add(new JLabel(\"City\"));\n" + + "panel.add(new JTextField(), new CC().wrap());\n" + + "panel.add(new JLabel(\"State\"));\n" + + "panel.add(new JTextField());\n" + + "panel.add(new JLabel(\"Postal Code\"));\n" + + "panel.add(new JTextField(10), new CC().spanX(2).growX(0));\n" + + "panel.add(new JLabel(\"Country\"));\n" + + "panel.add(new JTextField(), new CC().wrap());\n" + + "\n" + + "panel.add(new JButton(\"New\"), new CC().spanX(5).split(5).tag(\"other\"));\n" + + "panel.add(new JButton(\"Delete\"), new CC().tag(\"other\"));\n" + + "panel.add(new JButton(\"Edit\"), new CC().tag(\"other\"));\n" + + "panel.add(new JButton(\"Save\"), new CC().tag(\"other\"));\n" + + "panel.add(new JButton(\"Cancel\"), new CC().tag(\"cancel\"));\n" + + "\n" + + "tabbedPane.addTab(\"Layout Showdown (improved)\", panel);"); + + return tabbedPane; + } + + public JComponent createAPI_Constraints2() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + LC layC = new LC().fill().wrap(); + AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1); + AC rowC = new AC().index(6).gap("15!").align("top").grow(100, 8); + + JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient + + // References to text fields not stored to reduce code clutter. + + panel.add(new JLabel("Last Name")); + panel.add(new JTextField()); + panel.add(new JLabel("First Name")); + panel.add(new JTextField(), new CC().wrap()); + panel.add(new JLabel("Phone")); + panel.add(new JTextField()); + panel.add(new JLabel("Email")); + panel.add(new JTextField()); + panel.add(new JLabel("Address 1")); + panel.add(new JTextField(), new CC().spanX().growX()); + panel.add(new JLabel("Address 2")); + panel.add(new JTextField(), new CC().spanX().growX()); + panel.add(new JLabel("City")); + panel.add(new JTextField(), new CC().wrap()); + panel.add(new JLabel("State")); + panel.add(new JTextField()); + panel.add(new JLabel("Postal Code")); + panel.add(new JTextField(10), new CC().spanX(2).growX(0)); + panel.add(new JLabel("Country")); + panel.add(new JTextField(), new CC().wrap()); + + panel.add(createButton("New"), new CC().spanX(5).split(5).tag("other")); + panel.add(createButton("Delete"), new CC().tag("other")); + panel.add(createButton("Edit"), new CC().tag("other")); + panel.add(createButton("Save"), new CC().tag("other")); + panel.add(createButton("Cancel"), new CC().tag("cancel")); + + tabbedPane.addTab("Layout Showdown (improved)", panel); + + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "LC layC = new LC().fill().wrap();\n" + + "AC colC = new AC().align(\"right\", 0).fill(1, 3).grow(100, 1, 3).align(\"right\", 2).gap(\"15\", 1);\n" + + "AC rowC = new AC().index(6).gap(\"15!\").align(\"top\").grow(100, 8);\n" + + "\n" + + "JPanel panel = createTabPanel(new MigLayout(layC, colC, rowC)); // Makes the background gradient\n" + + "\n" + + "// References to text fields not stored to reduce code clutter.\n" + + "\n" + + "panel.add(new JLabel(\"Last Name\"));\n" + + "panel.add(new JTextField());\n" + + "panel.add(new JLabel(\"First Name\"));\n" + + "panel.add(new JTextField(), new CC().wrap());\n" + + "panel.add(new JLabel(\"Phone\"));\n" + + "panel.add(new JTextField());\n" + + "panel.add(new JLabel(\"Email\"));\n" + + "panel.add(new JTextField());\n" + + "panel.add(new JLabel(\"Address 1\"));\n" + + "panel.add(new JTextField(), new CC().spanX().growX());\n" + + "panel.add(new JLabel(\"Address 2\"));\n" + + "panel.add(new JTextField(), new CC().spanX().growX());\n" + + "panel.add(new JLabel(\"City\"));\n" + + "panel.add(new JTextField(), new CC().wrap());\n" + + "panel.add(new JLabel(\"State\"));\n" + + "panel.add(new JTextField());\n" + + "panel.add(new JLabel(\"Postal Code\"));\n" + + "panel.add(new JTextField(10), new CC().spanX(2).growX(0));\n" + + "panel.add(new JLabel(\"Country\"));\n" + + "panel.add(new JTextField(), new CC().wrap());\n" + + "\n" + + "panel.add(createButton(\"New\"), new CC().spanX(5).split(5).tag(\"other\"));\n" + + "panel.add(createButton(\"Delete\"), new CC().tag(\"other\"));\n" + + "panel.add(createButton(\"Edit\"), new CC().tag(\"other\"));\n" + + "panel.add(createButton(\"Save\"), new CC().tag(\"other\"));\n" + + "panel.add(createButton(\"Cancel\"), new CC().tag(\"cancel\"));\n" + + "\n" + + "tabbedPane.addTab(\"Layout Showdown (improved)\", panel);"); + + return tabbedPane; + } + + public JComponent createLayout_Showdown() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + JPanel p = createTabPanel(new MigLayout("", "[]15[][grow,fill]15[grow]")); + + JScrollPane list1 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"})); + + p.add(list1, "spany, growy, wmin 150"); + p.add(new JLabel("Last Name")); + p.add(new JTextField()); + p.add(new JLabel("First Name"), "split"); // split divides the cell + p.add(new JTextField(), "growx, wrap"); + p.add(new JLabel("Phone")); + p.add(new JTextField()); + p.add(new JLabel("Email"), "split"); + p.add(new JTextField(), "growx, wrap"); + p.add(new JLabel("Address 1")); + p.add(new JTextField(), "span, growx"); // span merges cells + p.add(new JLabel("Address 2")); + p.add(new JTextField(), "span, growx"); + p.add(new JLabel("City")); + p.add(new JTextField(), "wrap"); // wrap continues on next line + p.add(new JLabel("State")); + p.add(new JTextField()); + p.add(new JLabel("Postal Code"), "split"); + p.add(new JTextField(), "growx, wrap"); + p.add(new JLabel("Country")); + p.add(new JTextField(), "wrap 15"); + + p.add(createButton("New"), "span, split, align left"); + p.add(createButton("Delete"), ""); + p.add(createButton("Edit"), ""); + p.add(createButton("Save"), ""); + p.add(createButton("Cancel"), "wrap push"); + + tabbedPane.addTab("Layout Showdown (pure)", p); + + + // Fixed version ******************************************* + + JPanel p2 = createTabPanel(new MigLayout("", "[]15[][grow,fill]15[][grow,fill]")); // Makes the background gradient + + // References to text fields not stored to reduce code clutter. + + JScrollPane list2 = new JScrollPane(new JList(new String[] {"Mouse, Mickey"})); + p2.add(list2, "spany, growy, wmin 150"); + p2.add(new JLabel("Last Name")); + p2.add(new JTextField()); + p2.add(new JLabel("First Name")); + p2.add(new JTextField(), "wrap"); + p2.add(new JLabel("Phone")); + p2.add(new JTextField()); + p2.add(new JLabel("Email")); + p2.add(new JTextField(), "wrap"); + p2.add(new JLabel("Address 1")); + p2.add(new JTextField(), "span"); + p2.add(new JLabel("Address 2")); + p2.add(new JTextField(), "span"); + p2.add(new JLabel("City")); + p2.add(new JTextField(), "wrap"); + p2.add(new JLabel("State")); + p2.add(new JTextField()); + p2.add(new JLabel("Postal Code")); + p2.add(new JTextField(10), "growx 0, wrap"); + p2.add(new JLabel("Country")); + p2.add(new JTextField(), "wrap 15"); + + p2.add(createButton("New"), "tag other, span, split"); + p2.add(createButton("Delete"), "tag other"); + p2.add(createButton("Edit"), "tag other"); + p2.add(createButton("Save"), "tag other"); + p2.add(createButton("Cancel"), "tag cancel, wrap push"); + + tabbedPane.addTab("Layout Showdown (improved)", p2); + + + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "JPanel p = createTabPanel(new MigLayout(\"\", \"[]15[][grow,fill]15[grow]\"));\n" + + "\n" + + "JScrollPane list1 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" + + "\n" + + "p.add(list1, \"spany, growy, wmin 150\");\n" + + "p.add(new JLabel(\"Last Name\"));\n" + + "p.add(new JTextField());\n" + + "p.add(new JLabel(\"First Name\"), \"split\"); // split divides the cell\n" + + "p.add(new JTextField(), \"growx, wrap\");\n" + + "p.add(new JLabel(\"Phone\"));\n" + + "p.add(new JTextField());\n" + + "p.add(new JLabel(\"Email\"), \"split\");\n" + + "p.add(new JTextField(), \"growx, wrap\");\n" + + "p.add(new JLabel(\"Address 1\"));\n" + + "p.add(new JTextField(), \"span, growx\"); // span merges cells\n" + + "p.add(new JLabel(\"Address 2\"));\n" + + "p.add(new JTextField(), \"span, growx\");\n" + + "p.add(new JLabel(\"City\"));\n" + + "p.add(new JTextField(), \"wrap\"); // wrap continues on next line\n" + + "p.add(new JLabel(\"State\"));\n" + + "p.add(new JTextField());\n" + + "p.add(new JLabel(\"Postal Code\"), \"split\");\n" + + "p.add(new JTextField(), \"growx, wrap\");\n" + + "p.add(new JLabel(\"Country\"));\n" + + "p.add(new JTextField(), \"wrap 15\");\n" + + "\n" + + "p.add(createButton(\"New\"), \"span, split, align left\");\n" + + "p.add(createButton(\"Delete\"), \"\");\n" + + "p.add(createButton(\"Edit\"), \"\");\n" + + "p.add(createButton(\"Save\"), \"\");\n" + + "p.add(createButton(\"Cancel\"), \"wrap push\");\n" + + "\n" + + "tabbedPane.addTab(\"Layout Showdown (pure)\", p);" + + "\n" + + "\t\t// Fixed version *******************************************\n" + + "JPanel p2 = createTabPanel(new MigLayout(\"\", \"[]15[][grow,fill]15[][grow,fill]\")); // Makes the background gradient\n" + + "\n" + + "// References to text fields not stored to reduce code clutter.\n" + + "\n" + + "JScrollPane list2 = new JScrollPane(new JList(new String[] {\"Mouse, Mickey\"}));\n" + + "p2.add(list2, \"spany, growy, wmin 150\");\n" + + "p2.add(new JLabel(\"Last Name\"));\n" + + "p2.add(new JTextField());\n" + + "p2.add(new JLabel(\"First Name\"));\n" + + "p2.add(new JTextField(), \"wrap\");\n" + + "p2.add(new JLabel(\"Phone\"));\n" + + "p2.add(new JTextField());\n" + + "p2.add(new JLabel(\"Email\"));\n" + + "p2.add(new JTextField(), \"wrap\");\n" + + "p2.add(new JLabel(\"Address 1\"));\n" + + "p2.add(new JTextField(), \"span\");\n" + + "p2.add(new JLabel(\"Address 2\"));\n" + + "p2.add(new JTextField(), \"span\");\n" + + "p2.add(new JLabel(\"City\"));\n" + + "p2.add(new JTextField(), \"wrap\");\n" + + "p2.add(new JLabel(\"State\"));\n" + + "p2.add(new JTextField());\n" + + "p2.add(new JLabel(\"Postal Code\"));\n" + + "p2.add(new JTextField(10), \"growx 0, wrap\");\n" + + "p2.add(new JLabel(\"Country\"));\n" + + "p2.add(new JTextField(), \"wrap 15\");\n" + + "\n" + + "p2.add(createButton(\"New\"), \"tag other, span, split\");\n" + + "p2.add(createButton(\"Delete\"), \"tag other\");\n" + + "p2.add(createButton(\"Edit\"), \"tag other\");\n" + + "p2.add(createButton(\"Save\"), \"tag other\");\n" + + "p2.add(createButton(\"Cancel\"), \"tag cancel, wrap push\");\n" + + "\n" + + "tabbedPane.addTab(\"Layout Showdown (improved)\", p2);"); + + return tabbedPane; + } + + public JComponent createWelcome() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + MigLayout lm = new MigLayout("ins 20, fill", "", "[grow]unrel[]"); + + JPanel mainPanel = createTabPanel(lm); + + String s = "MigLayout's main purpose is to make layouts for SWT and Swing, and possibly other frameworks, much more powerful and a lot easier to create, especially for manual coding.\n\n" + + "The motto is: \"MigLayout makes complex layouts easy and normal layouts one-liners.\"\n\n" + + "The layout engine is very flexible and advanced, something that is needed to make it simple to use yet handle almost all layout use-cases.\n\n" + + "MigLayout can handle all layouts that the commonly used Swing Layout Managers can handle and this with a lot of extra features. " + + "It also incorporates most, if not all, of the open source alternatives FormLayout's and TableLayout's functionality." + + "\n\n\nThanks to Karsten Lentzsch of JGoodies.com for allowing the reuse of the main demo application layout and for his inspiring talks that led to this layout Manager." + + "\n\n\nMikael Grev\n" + + "MiG InfoCom AB\n" + + "miglayout@miginfocom.com"; + + JTextArea textArea = new JTextArea(s); + textArea.setEditable(false); + textArea.setSize(400, 400); + + if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.WINDOWS_XP) + textArea.setFont(new Font("tahoma", Font.BOLD, 11)); + + textArea.setOpaque(OPAQUE); + textArea.setWrapStyleWord(true); + textArea.setLineWrap(true); + + JLabel label = new JLabel("You can Right Click any Component or Container to change the constraints for it!"); + label.setForeground(new Color(200, 0, 0)); + + mainPanel.add(textArea, "w 500:pref,ay top,grow,wrap"); + mainPanel.add(label, "growx"); + label.setFont(label.getFont().deriveFont(Font.BOLD)); + + tabbedPane.addTab("Welcome", mainPanel); + + setSource(""); + + return tabbedPane; + } + + public JComponent createVisual_Bounds() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // "NON"-corrected bounds + JPanel p1 = createTabPanel(new MigLayout("fill, ins 3, novisualpadding")); + p1.setBorder(new LineBorder(Color.BLACK)); + + JTabbedPane demoPane2 = new JTabbedPane(); + JPanel demoPanel2 = new JPanel(); + demoPanel2.setBackground(Color.WHITE); + demoPane2.addTab("Demo Tab", demoPanel2); + + p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100"); + p1.add(demoPane2, "grow, aligny bottom"); + p1.add(createTextField("A JTextField", 100), "grow, aligny bottom, wmin 100"); + p1.add(createTextArea("A JTextArea", 1, 100), "newline,grow, aligny bottom, wmin 100"); + p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100"); + p1.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100"); + + JPanel p2 = createTabPanel(new MigLayout("center,center,fill,ins 3")); + p2.setBorder(new LineBorder(Color.BLACK)); + + JTabbedPane demoPane = new JTabbedPane(); + JPanel demoPanel = new JPanel(); + demoPanel.setBackground(Color.WHITE); + demoPane.addTab("Demo Tab", demoPanel); + + p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100"); + p2.add(demoPane, "grow, aligny bottom"); + p2.add(createTextField("A JTextField", 100), "grow, aligny bottom, wmin 100"); + p2.add(createTextArea("A JTextArea", 1, 100), "newline,grow, aligny bottom, wmin 100"); + p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100"); + p2.add(createTextArea("A JTextArea", 1, 100), "grow, aligny bottom, wmin 100"); + + tabbedPane.addTab("Visual Bounds (Not Corrected)", p1); + tabbedPane.addTab("Visual Bounds (Corrected on XP)", p2); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// \"NON\"-corrected bounds\n" + + "JPanel p1 = createTabPanel(new MigLayout(\"fill, ins 3, novisualpadding\"));\n" + + "p1.setBorder(new LineBorder(Color.BLACK));\n" + + "\n" + + "JTabbedPane demoPane2 = new JTabbedPane();\n" + + "JPanel demoPanel2 = new JPanel();\n" + + "demoPanel2.setBackground(Color.WHITE);\n" + + "demoPane2.addTab(\"Demo Tab\", demoPanel2);\n" + + "\n" + + "p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" + + "p1.add(demoPane2, \"grow, aligny bottom\");\n" + + "p1.add(createTextField(\"A JTextField\", 100), \"grow, aligny bottom, wmin 100\");\n" + + "p1.add(createTextArea(\"A JTextArea\", 1, 100), \"newline,grow, aligny bottom, wmin 100\");\n" + + "p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" + + "p1.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" + + "\n" + + "JPanel p2 = createTabPanel(new MigLayout(\"center,center,fill,ins 3\"));\n" + + "p2.setBorder(new LineBorder(Color.BLACK));\n" + + "\n" + + "JTabbedPane demoPane = new JTabbedPane();\n" + + "JPanel demoPanel = new JPanel();\n" + + "demoPanel.setBackground(Color.WHITE);\n" + + "demoPane.addTab(\"Demo Tab\", demoPanel);\n" + + "\n" + + "p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" + + "p2.add(demoPane, \"grow, aligny bottom\");\n" + + "p2.add(createTextField(\"A JTextField\", 100), \"grow, aligny bottom, wmin 100\");\n" + + "p2.add(createTextArea(\"A JTextArea\", 1, 100), \"newline,grow, aligny bottom, wmin 100\");\n" + + "p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" + + "p2.add(createTextArea(\"A JTextArea\", 1, 100), \"grow, aligny bottom, wmin 100\");\n" + + "\n" + + "tabbedPane.addTab(\"Visual Bounds (Not Corrected)\", p1);\n" + + "tabbedPane.addTab(\"Visual Bounds (Corrected on XP)\", p2);"); + + return tabbedPane; + } + + public JComponent createDocking() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + JPanel p1 = createTabPanel(new MigLayout("fill")); + + p1.add(createPanel("1. North"), "north"); + p1.add(createPanel("2. West"), "west"); + p1.add(createPanel("3. East"), "east"); + p1.add(createPanel("4. South"), "south"); + + String[][] data = new String[20][6]; + for (int r = 0; r < data.length; r++) { + data[r] = new String[6]; + for (int c = 0; c < data[r].length; c++) + data[r][c] = "Cell " + (r + 1) + ", " + (c + 1); + } + JTable table = new JTable(data, new String[] {"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6"}); + p1.add(new JScrollPane(table), "grow"); + + JPanel p2 = createTabPanel(new MigLayout("fill", "[c]", "")); + + p2.add(createPanel("1. North"), "north"); + p2.add(createPanel("2. North"), "north"); + p2.add(createPanel("3. West"), "west"); + p2.add(createPanel("4. West"), "west"); + p2.add(createPanel("5. South"), "south"); + p2.add(createPanel("6. East"), "east"); + p2.add(createButton("7. Normal")); + p2.add(createButton("8. Normal")); + p2.add(createButton("9. Normal")); + + JPanel p3 = createTabPanel(new MigLayout()); + + p3.add(createPanel("1. North"), "north"); + p3.add(createPanel("2. South"), "south"); + p3.add(createPanel("3. West"), "west"); + p3.add(createPanel("4. East"), "east"); + p3.add(createButton("5. Normal")); + + JPanel p4 = createTabPanel(new MigLayout()); + + p4.add(createPanel("1. North"), "north"); + p4.add(createPanel("2. North"), "north"); + p4.add(createPanel("3. West"), "west"); + p4.add(createPanel("4. West"), "west"); + p4.add(createPanel("5. South"), "south"); + p4.add(createPanel("6. East"), "east"); + p4.add(createButton("7. Normal")); + p4.add(createButton("8. Normal")); + p4.add(createButton("9. Normal")); + + JPanel p5 = createTabPanel(new MigLayout("fillx", "[c]", "")); + + p5.add(createPanel("1. North"), "north"); + p5.add(createPanel("2. North"), "north"); + p5.add(createPanel("3. West"), "west"); + p5.add(createPanel("4. West"), "west"); + p5.add(createPanel("5. South"), "south"); + p5.add(createPanel("6. East"), "east"); + p5.add(createButton("7. Normal")); + p5.add(createButton("8. Normal")); + p5.add(createButton("9. Normal")); + + JPanel p6 = createTabPanel(new MigLayout("fill", "", "")); + + Random rand = new Random(); + String[] sides = {"north", "east", "south", "west"}; + for (int i = 0; i < 20; i++) { + int side = rand.nextInt(4); + p6.add(createPanel((i + 1) + " " + sides[side]), sides[side]); + } + p6.add(createPanel("I'm in the Center!"), "dock center"); + + tabbedPane.addTab("Docking 1 (fill)", p1); + tabbedPane.addTab("Docking 2 (fill)", p2); + tabbedPane.addTab("Docking 3", p3); + tabbedPane.addTab("Docking 4", p4); + tabbedPane.addTab("Docking 5 (fillx)", p5); + tabbedPane.addTab("Random Docking", new JScrollPane(p6)); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "JPanel p1 = createTabPanel(new MigLayout(\"fill\"));\n" + + "\n" + + "p1.add(createPanel(\"1. North\"), \"north\");\n" + + "p1.add(createPanel(\"2. West\"), \"west\");\n" + + "p1.add(createPanel(\"3. East\"), \"east\");\n" + + "p1.add(createPanel(\"4. South\"), \"south\");\n" + + "\n" + + "String[][] data = new String[20][6];\n" + + "for (int r = 0; r < data.length; r++) {\n" + + "\tdata[r] = new String[6];\n" + + "\tfor (int c = 0; c < data[r].length; c++)\n" + + "\t\tdata[r][c] = \"Cell \" + (r + 1) + \", \" + (c + 1);\n" + + "}\n" + + "JTable table = new JTable(data, new String[] {\"Column 1\", \"Column 2\", \"Column 3\", \"Column 4\", \"Column 5\", \"Column 6\"});\n" + + "p1.add(new JScrollPane(table), \"grow\");\n" + + "\n" + + "JPanel p2 = createTabPanel(new MigLayout(\"fill\", \"[c]\", \"\"));\n" + + "\n" + + "p2.add(createPanel(\"1. North\"), \"north\");\n" + + "p2.add(createPanel(\"2. North\"), \"north\");\n" + + "p2.add(createPanel(\"3. West\"), \"west\");\n" + + "p2.add(createPanel(\"4. West\"), \"west\");\n" + + "p2.add(createPanel(\"5. South\"), \"south\");\n" + + "p2.add(createPanel(\"6. East\"), \"east\");\n" + + "p2.add(createButton(\"7. Normal\"));\n" + + "p2.add(createButton(\"8. Normal\"));\n" + + "p2.add(createButton(\"9. Normal\"));\n" + + "\n" + + "JPanel p3 = createTabPanel(new MigLayout());\n" + + "\n" + + "p3.add(createPanel(\"1. North\"), \"north\");\n" + + "p3.add(createPanel(\"2. South\"), \"south\");\n" + + "p3.add(createPanel(\"3. West\"), \"west\");\n" + + "p3.add(createPanel(\"4. East\"), \"east\");\n" + + "p3.add(createButton(\"5. Normal\"));\n" + + "\n" + + "JPanel p4 = createTabPanel(new MigLayout());\n" + + "\n" + + "p4.add(createPanel(\"1. North\"), \"north\");\n" + + "p4.add(createPanel(\"2. North\"), \"north\");\n" + + "p4.add(createPanel(\"3. West\"), \"west\");\n" + + "p4.add(createPanel(\"4. West\"), \"west\");\n" + + "p4.add(createPanel(\"5. South\"), \"south\");\n" + + "p4.add(createPanel(\"6. East\"), \"east\");\n" + + "p4.add(createButton(\"7. Normal\"));\n" + + "p4.add(createButton(\"8. Normal\"));\n" + + "p4.add(createButton(\"9. Normal\"));\n" + + "\n" + + "JPanel p5 = createTabPanel(new MigLayout(\"fillx\", \"[c]\", \"\"));\n" + + "\n" + + "p5.add(createPanel(\"1. North\"), \"north\");\n" + + "p5.add(createPanel(\"2. North\"), \"north\");\n" + + "p5.add(createPanel(\"3. West\"), \"west\");\n" + + "p5.add(createPanel(\"4. West\"), \"west\");\n" + + "p5.add(createPanel(\"5. South\"), \"south\");\n" + + "p5.add(createPanel(\"6. East\"), \"east\");\n" + + "p5.add(createButton(\"7. Normal\"));\n" + + "p5.add(createButton(\"8. Normal\"));\n" + + "p5.add(createButton(\"9. Normal\"));\n" + + "\n" + + "JPanel p6 = createTabPanel(new MigLayout(\"fill\", \"\", \"\"));\n" + + "\n" + + "Random rand = new Random();\n" + + "String[] sides = {\"north\", \"east\", \"south\", \"west\"};\n" + + "for (int i = 0; i < 20; i++) {\n" + + "\tint side = rand.nextInt(4);\n" + + "\tp6.add(createPanel((i + 1) + \" \" + sides[side]), sides[side]);\n" + + "}\n" + + "p6.add(createButton(\"I'm in the middle!\"), \"grow\");\n" + + "\n" + + "tabbedPane.addTab(\"Docking 1 (fill)\", p1);\n" + + "tabbedPane.addTab(\"Docking 2 (fill)\", p2);\n" + + "tabbedPane.addTab(\"Docking 3\", p3);\n" + + "tabbedPane.addTab(\"Docking 4\", p4);\n" + + "tabbedPane.addTab(\"Docking 5 (fillx)\", p5);\n" + + "tabbedPane.addTab(\"Docking Spiral\", new JScrollPane(p6));"); + + return tabbedPane; + } + + public JComponent createAbsolute_Position() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // Pos tab + final JPanel posPanel = createTabPanel(new MigLayout()); + + posPanel.add(createButton(), "pos 0.5al 0al"); + posPanel.add(createButton(), "pos 1al 0al"); + posPanel.add(createButton(), "pos 0.5al 0.5al"); + posPanel.add(createButton(), "pos 5in 45lp"); + posPanel.add(createButton(), "pos 0.5al 0.5al"); + posPanel.add(createButton(), "pos 0.5al 1.0al"); + posPanel.add(createButton(), "pos 1al .25al"); + posPanel.add(createButton(), "pos visual.x2-pref visual.y2-pref"); + posPanel.add(createButton(), "pos 1al -1in"); + posPanel.add(createButton(), "pos 100 100"); + posPanel.add(createButton(), "pos (10+(20*3lp)) 200"); + posPanel.add(createButton("Drag Window! (pos 500-container.xpos 500-container.ypos)"), + "pos 500-container.xpos 500-container.ypos"); + + // Bounds tab + JPanel boundsPanel = createTabPanel(new MigLayout()); + + String constr = "pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2"; + JLabel southLabel = createLabel(constr, SwingConstants.CENTER); + southLabel.setBorder(new LineBorder(Color.LIGHT_GRAY, 1)); + southLabel.setBackground(new Color(200, 200, 255, benchRuns == 0 ? 70 : 255)); + southLabel.setOpaque(true); + southLabel.setFont(southLabel.getFont().deriveFont(Font.BOLD)); + boundsPanel.add(southLabel, constr); + + boundsPanel.add(createButton(), "pos 0 0 container.x2 n"); + boundsPanel.add(createButton(), "pos visual.x 40 visual.x2 70"); + boundsPanel.add(createButton(), "pos visual.x 100 visual.x2 p"); + boundsPanel.add(createButton(), "pos 0.1al 0.4al n (visual.y2 - 10)"); + boundsPanel.add(createButton(), "pos 0.9al 0.4al n visual.y2-10"); + boundsPanel.add(createButton(), "pos 0.5al 0.5al, pad 3 0 -3 0"); + boundsPanel.add(createButton(), "pos n n 50% 50%"); + boundsPanel.add(createButton(), "pos 50% 50% n n"); + boundsPanel.add(createButton(), "pos 50% n n 50%"); + boundsPanel.add(createButton(), "pos n 50% 50% n"); + + tabbedPane.addTab("X Y Positions", posPanel); + tabbedPane.addTab("X1 Y1 X2 Y2 Bounds", boundsPanel); + + // Glass pane tab + if (benchRuns == 0) { + final JPanel glassPanel = createTabPanel(new MigLayout("align c c, ins 0")); + final JButton butt = createButton("Press me!!"); + glassPanel.add(butt); + + butt.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + butt.setEnabled(false); + final JPanel bg = new JPanel(new MigLayout("align c c,fill")) { + public void paint(Graphics g) + { + g.setColor(getBackground()); + g.fillRect(0, 0, getWidth(), getHeight()); + super.paint(g); + } + }; + bg.setOpaque(OPAQUE); + configureActiveComponet(bg); + + final JLabel label = createLabel("You don't need a GlassPane to be cool!"); + label.setFont(label.getFont().deriveFont(30f)); + label.setForeground(new Color(255, 255, 255, 0)); + bg.add(label, "align 50% 30%"); + + glassPanel.add(bg, "pos visual.x visual.y visual.x2 visual.y2", 0); + final long startTime = System.nanoTime(); + final long endTime = startTime + 500000000L; + + glassPanel.revalidate(); + + final javax.swing.Timer timer = new Timer(25, null); + + timer.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + long now = System.nanoTime(); + int alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300); + if (alpha < 150) + bg.setBackground(new Color(100, 100, 100, alpha)); + + if (alpha > 150 && alpha < 405) { + label.setForeground(new Color(255, 255, 255, (alpha - 150))); + bg.repaint(); + } + if (alpha > 405) + timer.stop(); + } + }); + timer.start(); + } + }); + tabbedPane.addTab("GlassPane Substitute", glassPanel); + addComponentListener(new ComponentAdapter() { + public void componentMoved(ComponentEvent e) { + if (posPanel.isDisplayable()) { + posPanel.revalidate(); + } else { + removeComponentListener(this); + } + } + }); + } + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// Pos tab\n" + + "final JPanel posPanel = createTabPanel(new MigLayout());\n" + + "\n" + + "posPanel.add(createButton(), \"pos 0.5al 0al\");\n" + + "posPanel.add(createButton(), \"pos 1al 0al\");\n" + + "posPanel.add(createButton(), \"pos 0.5al 0.5al\");\n" + + "posPanel.add(createButton(), \"pos 5in 45lp\");\n" + + "posPanel.add(createButton(), \"pos 0.5al 0.5al\");\n" + + "posPanel.add(createButton(), \"pos 0.5al 1.0al\");\n" + + "posPanel.add(createButton(), \"pos 1al .25al\");\n" + + "posPanel.add(createButton(), \"pos visual.x2-pref visual.y2-pref\");\n" + + "posPanel.add(createButton(), \"pos 1al -1in\");\n" + + "posPanel.add(createButton(), \"pos 100 100\");\n" + + "posPanel.add(createButton(), \"pos (10+(20*3lp)) 200\");\n" + + "posPanel.add(createButton(\"Drag Window! (pos 500-container.xpos 500-container.ypos)\"),\n" + + " \"pos 500-container.xpos 500-container.ypos\");\n" + + "\n" + + "// Bounds tab\n" + + "JPanel boundsPanel = createTabPanel(new MigLayout());\n" + + "\n" + + "String constr = \"pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2\";\n" + + "JLabel southLabel = createLabel(constr, SwingConstants.CENTER);\n" + + "southLabel.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));\n" + + "southLabel.setBackground(new Color(200, 200, 255, 70));\n" + + "southLabel.setOpaque(true);\n" + + "southLabel.setFont(southLabel.getFont().deriveFont(Font.BOLD));\n" + + "boundsPanel.add(southLabel, constr);\n" + + "\n" + + "boundsPanel.add(createButton(), \"pos 0 0 container.x2 n\");\n" + + "boundsPanel.add(createButton(), \"pos visual.x 40 visual.x2 70\");\n" + + "boundsPanel.add(createButton(), \"pos visual.x 100 visual.x2 p\");\n" + + "boundsPanel.add(createButton(), \"pos 0.1al 0.4al n visual.y2-10\");\n" + + "boundsPanel.add(createButton(), \"pos 0.9al 0.4al n visual.y2-10\");\n" + + "boundsPanel.add(createButton(), \"pos 0.5al 0.5al, pad 3 0 -3 0\");\n" + + "boundsPanel.add(createButton(), \"pos n n 50% 50%\");\n" + + "boundsPanel.add(createButton(), \"pos 50% 50% n n\");\n" + + "boundsPanel.add(createButton(), \"pos 50% n n 50%\");\n" + + "boundsPanel.add(createButton(), \"pos n 50% 50% n\");\n" + + "\n" + + "// Glass pane tab\n" + + "final JPanel glassPanel = createTabPanel(new MigLayout(\"align c c, ins 0\"));\n" + + "final JButton butt = createButton(\"Press me!!\");\n" + + "glassPanel.add(butt);\n" + + "\n" + + "butt.addActionListener(new ActionListener()\t\t{\n" + + "\tpublic void actionPerformed(ActionEvent e)\n" + + "\t{\n" + + "\t\tbutt.setEnabled(false);\n" + + "\t\tfinal JPanel bg = new JPanel(new MigLayout(\"align c c,fill\")) {\n" + + "\t\t\tpublic void paint(Graphics g)\n" + + "\t\t\t{\n" + + "\t\t\t\tg.setColor(getBackground());\n" + + "\t\t\t\tg.fillRect(0, 0, getWidth(), getHeight());\n" + + "\t\t\t\tsuper.paint(g);\n" + + "\t\t\t}\n" + + "\t\t};\n" + + "\t\tbg.setOpaque(OPAQUE);\n" + + "\t\tconfigureActiveComponet(bg);\n" + + "\n" + + "\t\tfinal JLabel label = createLabel(\"You don't need a GlassPane to be cool!\");\n" + + "\t\tlabel.setFont(label.getFont().deriveFont(30f));\n" + + "\t\tlabel.setForeground(new Color(255, 255, 255, 0));\n" + + "\t\tbg.add(label, \"align 50% 30%\");\n" + + "\n" + + "\t\tglassPanel.add(bg, \"pos visual.x visual.y visual.x2 visual.y2\", 0);\n" + + "\t\tfinal long startTime = System.nanoTime();\n" + + "\t\tfinal long endTime = startTime + 500000000L;\n" + + "\n" + + "\t\tglassPanel.revalidate();\n" + + "\n" + + "\t\tfinal javax.swing.Timer timer = new Timer(25, null);\n" + + "\n" + + "\t\ttimer.addActionListener(new ActionListener() {\n" + + "\t\t\tpublic void actionPerformed(ActionEvent e)\n" + + "\t\t\t{\n" + + "\t\t\t\tlong now = System.nanoTime();\n" + + "\t\t\t\tint alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300);\n" + + "\t\t\t\tif (alpha < 150)\n" + + "\t\t\t\t\tbg.setBackground(new Color(100, 100, 100, alpha));\n" + + "\n" + + "\t\t\t\tif (alpha > 150 && alpha < 405) {\n" + + "\t\t\t\t\tlabel.setForeground(new Color(255, 255, 255, (alpha - 150)));\n" + + "\t\t\t\t\tbg.repaint();\n" + + "\t\t\t\t}\n" + + "\t\t\t\tif (alpha > 405)\n" + + "\t\t\t\t\ttimer.stop();\n" + + "\t\t\t}\n" + + "\t\t});\n" + + "\t\ttimer.start();\n" + + "\t}\n" + + "});\n" + + "\n" + + "tabbedPane.addTab(\"X Y Positions\", posPanel);\n" + + "tabbedPane.addTab(\"X1 Y1 X2 Y2 Bounds\", boundsPanel);\n" + + "tabbedPane.addTab(\"GlassPane Substitute\", glassPanel);\n" + + "\n" + + "addComponentListener(new ComponentAdapter() {\n" + + "\tpublic void componentMoved(ComponentEvent e) {\n" + + "\t\tif (posPanel.isDisplayable()) {\n" + + "\t\t\tposPanel.revalidate();\n" + + "\t\t} else {\n" + + "\t\t\tremoveComponentListener(this);\n" + + "\t\t}\n" + + "\t}\n" + + "});"); + + return tabbedPane; + } + + public JComponent createComponent_Links() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + JPanel linksPanel = createTabPanel(new MigLayout()); + + // Links tab + JButton mini = createButton("Mini"); + mini.setMargin(new Insets(0, 1, 0, 1)); + linksPanel.add(mini, "pos null ta.y ta.x2 null"); + linksPanel.add(createTextArea("Components, Please Link to Me!\nMy ID is: 'ta'", 3, 30), "id ta, pos 0.5al 0.5al"); + linksPanel.add(createButton(), "id b1,pos ta.x2 ta.y2"); + linksPanel.add(createButton(), "pos b1.x2+rel b1.y visual.x2 null"); + linksPanel.add(createButton(), "pos ta.x2+rel ta.y visual.x2 null"); + linksPanel.add(createButton(), "pos null ta.y+(ta.h-pref)/2 ta.x-rel null"); + linksPanel.add(createButton(), "pos ta.x ta.y2+100 ta.x2 null"); + linksPanel.add(createCheck("pos (ta.x+indent) (ta.y2+rel)"), + "pos (ta.x+indent) (ta.y2+rel)"); + + // External tab + JPanel externalPanel = createTabPanel(new MigLayout()); + + JButton extButt = createButton("Bounds Externally Set!"); + extButt.setBounds(250, 130, 200, 40); + externalPanel.add(extButt, "id ext, external"); + externalPanel.add(createButton(), "pos ext.x2 ext.y2"); + externalPanel.add(createButton(), "pos null null ext.x ext.y"); + + // Start/End Group tab + JPanel egPanel = createTabPanel(new MigLayout()); + + egPanel.add(createButton(), "id b1, endgroupx g1, pos 200 200"); + egPanel.add(createButton(), "id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)"); + egPanel.add(createButton(), "id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)"); + egPanel.add(createButton(), "id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)"); + + // Group Bounds tab + JPanel gpPanel = createTabPanel(new MigLayout()); + + gpPanel.add(createButton(), "id grp1.b1, pos n 0.5al 50% n"); + gpPanel.add(createButton(), "id grp1.b2, pos 50% 0.5al n n"); + gpPanel.add(createButton(), "id grp1.b3, pos 0.5al n n b1.y"); + gpPanel.add(createButton(), "id grp1.b4, pos 0.5al b1.y2 n n"); + + gpPanel.add(createButton(), "pos n grp1.y2 grp1.x n"); + gpPanel.add(createButton(), "pos n n grp1.x grp1.y"); + gpPanel.add(createButton(), "pos grp1.x2 n n grp1.y"); + gpPanel.add(createButton(), "pos grp1.x2 grp1.y2"); + + JPanel boundsPanel = new JPanel(null); + boundsPanel.setBackground(new Color(200, 200, 255)); + gpPanel.add(boundsPanel, "pos grp1.x grp1.y grp1.x2 grp1.y2"); + + + tabbedPane.addTab("Component Links", linksPanel); + tabbedPane.addTab("External Components", externalPanel); + tabbedPane.addTab("End Grouping", egPanel); + tabbedPane.addTab("Group Bounds", gpPanel); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "JPanel linksPanel = createTabPanel(new MigLayout());\n" + + "\n" + + "// Links tab\n" + + "JButton mini = createButton(\"Mini\");\n" + + "mini.setMargin(new Insets(0, 1, 0, 1));\n" + + "linksPanel.add(mini, \"pos null ta.y ta.x2 null\");\n" + + "linksPanel.add(createTextArea(\"Components, Please Link to Me!\\nMy ID is: 'ta'\", 3, 30), \"id ta, pos 0.5al 0.5al\");\n" + + "linksPanel.add(createButton(), \"id b1,pos ta.x2 ta.y2\");\n" + + "linksPanel.add(createButton(), \"pos b1.x2+rel b1.y visual.x2 null\");\n" + + "linksPanel.add(createButton(), \"pos ta.x2+rel ta.y visual.x2 null\");\n" + + "linksPanel.add(createButton(), \"pos null ta.y+(ta.h-pref)/2 ta.x-rel null\");\n" + + "linksPanel.add(createButton(), \"pos ta.x ta.y2+100 ta.x2 null\");\n" + + "linksPanel.add(createCheck(\"pos (ta.x+indent) (ta.y2+rel)\"),\n" + + " \"pos (ta.x+indent) (ta.y2+rel)\");\n" + + "\n" + + "// External tab\n" + + "JPanel externalPanel = createTabPanel(new MigLayout());\n" + + "\n" + + "JButton extButt = createButton(\"Bounds Externally Set!\");\n" + + "extButt.setBounds(250, 130, 200, 40);\n" + + "externalPanel.add(extButt, \"id ext, external\");\n" + + "externalPanel.add(createButton(), \"pos ext.x2 ext.y2\");\n" + + "externalPanel.add(createButton(), \"pos null null ext.x ext.y\");\n" + + "\n" + + "// Start/End Group tab\n" + + "JPanel egPanel = createTabPanel(new MigLayout());\n" + + "\n" + + "egPanel.add(createButton(), \"id b1, endgroupx g1, pos 200 200\");\n" + + "egPanel.add(createButton(), \"id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)\");\n" + + "egPanel.add(createButton(), \"id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)\");\n" + + "egPanel.add(createButton(), \"id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)\");\n" + + "\n" + + "// Group Bounds tab\n" + + "JPanel gpPanel = createTabPanel(new MigLayout());\n" + + "\n" + + "gpPanel.add(createButton(), \"id grp1.b1, pos n 0.5al 50% n\");\n" + + "gpPanel.add(createButton(), \"id grp1.b2, pos 50% 0.5al n n\");\n" + + "gpPanel.add(createButton(), \"id grp1.b3, pos 0.5al n n b1.y\");\n" + + "gpPanel.add(createButton(), \"id grp1.b4, pos 0.5al b1.y2 n n\");\n" + + "\n" + + "gpPanel.add(createButton(), \"pos n grp1.y2 grp1.x n\");\n" + + "gpPanel.add(createButton(), \"pos n n grp1.x grp1.y\");\n" + + "gpPanel.add(createButton(), \"pos grp1.x2 n n grp1.y\");\n" + + "gpPanel.add(createButton(), \"pos grp1.x2 grp1.y2\");\n" + + "\n" + + "JPanel boundsPanel = new JPanel(null);\n" + + "boundsPanel.setBackground(new Color(200, 200, 255));\n" + + "gpPanel.add(boundsPanel, \"pos grp1.x grp1.y grp1.x2 grp1.y2\");\n" + + "\n" + + "\n" + + "tabbedPane.addTab(\"Component Links\", linksPanel);\n" + + "tabbedPane.addTab(\"External Components\", externalPanel);\n" + + "tabbedPane.addTab(\"End Grouping\", egPanel);\n" + + "tabbedPane.addTab(\"Group Bounds\", gpPanel);"); + + return tabbedPane; + } + + public JComponent createFlow_Direction() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + tabbedPane.addTab("Layout: flowx, Cell: flowx", createFlowPanel("", "flowx")); + tabbedPane.addTab("Layout: flowx, Cell: flowy", createFlowPanel("", "flowy")); + tabbedPane.addTab("Layout: flowy, Cell: flowx", createFlowPanel("flowy", "flowx")); + tabbedPane.addTab("Layout: flowy, Cell: flowy", createFlowPanel("flowy", "flowy")); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "tabbedPane.addTab(\"Layout: flowx, Cell: flowx\", createFlowPanel(\"\", \"flowx\"));\n" + + "tabbedPane.addTab(\"Layout: flowx, Cell: flowy\", createFlowPanel(\"\", \"flowy\"));\n" + + "tabbedPane.addTab(\"Layout: flowy, Cell: flowx\", createFlowPanel(\"flowy\", \"flowx\"));\n" + + "tabbedPane.addTab(\"Layout: flowy, Cell: flowy\", createFlowPanel(\"flowy\", \"flowy\"));" + + "\n\tpublic JPanel createFlowPanel(String gridFlow, String cellFlow)\n" + + "\t{\n" + + "MigLayout lm = new MigLayout(\"center, wrap 3,\" + gridFlow,\n" + + " \"[110,fill]\",\n" + + " \"[110,fill]\");\n" + + "JPanel panel = createTabPanel(lm);\n" + + "\n" + + "for (int i = 0; i < 9; i++) {\n" + + "\tJButton b = createButton(\"\" + (i + 1));\n" + + "\tb.setFont(b.getFont().deriveFont(20f));\n" + + "\tpanel.add(b, cellFlow);\n" + + "}\n" + + "\n" + + "JButton b = createButton(\"5:2\");\n" + + "b.setFont(b.getFont().deriveFont(20f));\n" + + "panel.add(b, cellFlow + \",cell 1 1\");\n" + + "\n" + + "return panel;\n" + + "\t}"); + + return tabbedPane; + } + + public JPanel createFlowPanel(String gridFlow, String cellFlow) + { + MigLayout lm = new MigLayout("center, wrap 3," + gridFlow, + "[110,fill]", + "[110,fill]"); + JPanel panel = createTabPanel(lm); + + Font f = panel.getFont().deriveFont(20f); + for (int i = 0; i < 9; i++) { + JComponent b = createPanel("" + (i + 1)); + b.setFont(f); + panel.add(b, cellFlow); + } + + JComponent b = createPanel("5:2"); + b.setFont(f); + panel.add(b, cellFlow + ",cell 1 1"); + + return panel; + } + + public JComponent createDebug() + { + return createPlainImpl(true); + } + + public JComponent createButton_Bars() + { + MigLayout lm = new MigLayout("ins 0 0 15lp 0", + "[grow]", + "[grow][baseline,nogrid]"); + + final JPanel mainPanel = new JPanel(lm); + final JLabel formatLabel = createLabel(""); + formatLabel.setFont(formatLabel.getFont().deriveFont(Font.BOLD)); + JTabbedPane tabbedPane = new JTabbedPane(); + + JToggleButton winButt = createToggleButton("Windows"); + JToggleButton macButt = createToggleButton("Mac OS X"); + JButton helpButt = createButton("Help"); + + if (benchRuns == 0) { + winButt.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP); + formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'"); + ((JPanel) ((JFrame) Frame.getFrames()[0]).getContentPane()).revalidate(); + } + }); + + macButt.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX); + formatLabel.setText(PlatformDefaults.getButtonOrder()); + ((JPanel) ((JFrame) Frame.getFrames()[0]).getContentPane()).revalidate(); + } + }); + + helpButt.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JOptionPane.showMessageDialog(mainPanel, "See JavaDoc for PlatformConverter.getButtonBarOrder(..) for details on the format string."); + } + }); + } + + ButtonGroup bg = new ButtonGroup(); + bg.add(winButt); + bg.add(macButt); + if (benchRuns == 0) { + if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.MAC_OSX) { + macButt.doClick(); + } else { + winButt.doClick(); + } + } + + tabbedPane.addTab("Buttons", createButtonBarsPanel("help", false)); + tabbedPane.addTab("Buttons with Help2", createButtonBarsPanel("help2", false)); + tabbedPane.addTab("Buttons (Same width)", createButtonBarsPanel("help", true)); + + mainPanel.add(tabbedPane, "grow,wrap"); + + mainPanel.add(createLabel("Button Order:")); + mainPanel.add(formatLabel, "growx"); + mainPanel.add(winButt); + mainPanel.add(macButt); + mainPanel.add(helpButt, "gapbefore unrel"); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("MigLayout lm = new MigLayout(\"ins 0 0 15lp 0\",\n" + + " \"[grow]\",\n" + + " \"[grow][baseline,nogrid,gap unrelated]\");\n" + + "\n" + + "final JPanel mainPanel = new JPanel(lm);\n" + + "final JLabel formatLabel = createLabel(\"\");\n" + + "formatLabel.setFont(formatLabel.getFont().deriveFont(Font.BOLD));\n" + + "JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "JToggleButton winButt = createToggleButton(\"Windows\");\n" + + "\n" + + "winButt.addActionListener(new ActionListener() {\n" + + "\tpublic void actionPerformed(ActionEvent e) {\n" + + "\t\tPlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP);\n" + + "\t\tformatLabel.setText(\"'\" + PlatformDefaults.getButtonOrder() + \"'\");\n" + + "\t\tSwingUtilities.updateComponentTreeUI(mainPanel);\n" + + "\t}\n" + + "});\n" + + "\n" + + "JToggleButton macButt = createToggleButton(\"Mac OS X\");\n" + + "macButt.addActionListener(new ActionListener() {\n" + + "\tpublic void actionPerformed(ActionEvent e) {\n" + + "\t\tPlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX);\n" + + "\t\tformatLabel.setText(PlatformDefaults.getButtonOrder());\n" + + "\t\tSwingUtilities.updateComponentTreeUI(mainPanel);\n" + + "\t}\n" + + "});\n" + + "\n" + + "JButton helpButt = createButton(\"Help\");\n" + + "helpButt.addActionListener(new ActionListener() {\n" + + "\tpublic void actionPerformed(ActionEvent e) {\n" + + "\t\tJOptionPane.showMessageDialog(mainPanel, \"See JavaDoc for PlatformConverter.getButtonBarOrder(..) for details on the format string.\");\n" + + "\t}\n" + + "});\n" + + "\n" + + "ButtonGroup bg = new ButtonGroup();\n" + + "bg.add(winButt);\n" + + "bg.add(macButt);\n" + + "winButt.doClick();\n" + + "\n" + + "tabbedPane.addTab(\"Buttons\", createButtonBarsPanel(\"help\", false));\n" + + "tabbedPane.addTab(\"Buttons with Help2\", createButtonBarsPanel(\"help2\", false));\n" + + "tabbedPane.addTab(\"Buttons (Same width)\", createButtonBarsPanel(\"help\", true));\n" + + "\n" + + "mainPanel.add(tabbedPane, \"grow,wrap\");\n" + + "\n" + + "mainPanel.add(createLabel(\"Button Order:\"));\n" + + "mainPanel.add(formatLabel, \"growx\");\n" + + "mainPanel.add(winButt);\n" + + "mainPanel.add(macButt);\n" + + "mainPanel.add(helpButt, \"gapbefore unrel\");"); + + return mainPanel; + } + + private JComponent createButtonBarsPanel(String helpTag, boolean sizeLocked) + { + MigLayout lm = new MigLayout("nogrid, fillx, aligny 100%, gapy unrel"); + JPanel panel = createTabPanel(lm); + + // Notice that the order in the rows below does not matter... + String[][] buttons = new String[][] { + {"OK"}, + {"No", "Yes"}, + {"Help", "Close"}, + {"OK", "Help"}, + {"OK", "Cancel", "Help"}, + {"OK", "Cancel", "Apply", "Help"}, + {"No", "Yes", "Cancel"}, + {"Help", "< Back", "Forward >", "Cancel"}, + {"Print...", "Cancel", "Help"} + }; + + for (int r = 0; r < buttons.length; r++) { + for (int i = 0; i < buttons[r].length; i++) { + String txt = buttons[r][i]; + String tag = txt; + + if (txt.equals("Help")) { + tag = helpTag; + } else if (txt.equals("< Back")) { + tag = "back"; + } else if (txt.equals("Close")) { + tag = "cancel"; + } else if (txt.equals("Forward >")) { + tag = "next"; + } else if (txt.equals("Print...")) { + tag = "other"; + } + String wrap = (i == buttons[r].length - 1) ? ",wrap" : ""; + String sizeGroup = sizeLocked ? ("sgx " + r + ",") : ""; + panel.add(createButton(txt), sizeGroup + "tag " + tag + wrap); + } + } + return panel; + } + + public JComponent createOrientation() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + MigLayout lm = new MigLayout("flowy", "[grow,fill]", "[]20[]20[]20[]"); + JPanel mainPanel = createTabPanel(lm); + + // Default orientation + MigLayout defLM = new MigLayout("", "[trailing][grow,fill]", ""); + + JPanel defPanel = createTabPanel(defLM); + addSeparator(defPanel, "Default Orientation"); + defPanel.add(createLabel("Level of Trust")); + defPanel.add(createTextField(""), "span,growx"); + defPanel.add(createLabel("Radar Presentation")); + defPanel.add(createTextField("")); + defPanel.add(createTextField("")); + + // Right-to-left, Top-to-bottom + MigLayout rtlLM = new MigLayout("rtl,ttb", + "[trailing][grow,fill]", + ""); + JPanel rtlPanel = createTabPanel(rtlLM); + addSeparator(rtlPanel, "Right to Left"); + rtlPanel.add(createLabel("Level of Trust")); + rtlPanel.add(createTextField(""), "span,growx"); + rtlPanel.add(createLabel("Radar Presentation")); + rtlPanel.add(createTextField("")); + rtlPanel.add(createTextField("")); + + // Right-to-left, Bottom-to-top + MigLayout rtlbLM = new MigLayout("rtl,btt", + "[trailing][grow,fill]", + ""); + JPanel rtlbPanel = createTabPanel(rtlbLM); + addSeparator(rtlbPanel, "Right to Left, Bottom to Top"); + rtlbPanel.add(createLabel("Level of Trust")); + rtlbPanel.add(createTextField(""), "span,growx"); + rtlbPanel.add(createLabel("Radar Presentation")); + rtlbPanel.add(createTextField("")); + rtlbPanel.add(createTextField("")); + + // Left-to-right, Bottom-to-top + MigLayout ltrbLM = new MigLayout("ltr,btt", + "[trailing][grow,fill]", + ""); + JPanel ltrbPanel = createTabPanel(ltrbLM); + addSeparator(ltrbPanel, "Left to Right, Bottom to Top"); + ltrbPanel.add(createLabel("Level of Trust")); + ltrbPanel.add(createTextField(""), "span,growx"); + ltrbPanel.add(createLabel("Radar Presentation")); + ltrbPanel.add(createTextField("")); + ltrbPanel.add(createTextField("")); + + mainPanel.add(defPanel); + mainPanel.add(rtlPanel); + mainPanel.add(rtlbPanel); + mainPanel.add(ltrbPanel); + + tabbedPane.addTab("Orientation", mainPanel); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "MigLayout lm = new MigLayout(\"flowy\", \"[grow,fill]\", \"[]0[]15lp[]0[]\");\n" + + "JPanel mainPanel = createTabPanel(lm);\n" + + "\n" + + "// Default orientation\n" + + "MigLayout defLM = new MigLayout(\"\", \"[][grow,fill]\", \"\");\n" + + "\n" + + "JPanel defPanel = createTabPanel(defLM);\n" + + "addSeparator(defPanel, \"Default Orientation\");\n" + + "defPanel.add(createLabel(\"Level\"));\n" + + "defPanel.add(createTextField(\"\"), \"span,growx\");\n" + + "defPanel.add(createLabel(\"Radar\"));\n" + + "defPanel.add(createTextField(\"\"));\n" + + "defPanel.add(createTextField(\"\"));\n" + + "\n" + + "// Right-to-left, Top-to-bottom\n" + + "MigLayout rtlLM = new MigLayout(\"rtl,ttb\",\n" + + " \"[][grow,fill]\",\n" + + " \"\");\n" + + "JPanel rtlPanel = createTabPanel(rtlLM);\n" + + "addSeparator(rtlPanel, \"Right to Left\");\n" + + "rtlPanel.add(createLabel(\"Level\"));\n" + + "rtlPanel.add(createTextField(\"\"), \"span,growx\");\n" + + "rtlPanel.add(createLabel(\"Radar\"));\n" + + "rtlPanel.add(createTextField(\"\"));\n" + + "rtlPanel.add(createTextField(\"\"));\n" + + "\n" + + "// Right-to-left, Bottom-to-top\n" + + "MigLayout rtlbLM = new MigLayout(\"rtl,btt\",\n" + + " \"[][grow,fill]\",\n" + + " \"\");\n" + + "JPanel rtlbPanel = createTabPanel(rtlbLM);\n" + + "addSeparator(rtlbPanel, \"Right to Left, Bottom to Top\");\n" + + "rtlbPanel.add(createLabel(\"Level\"));\n" + + "rtlbPanel.add(createTextField(\"\"), \"span,growx\");\n" + + "rtlbPanel.add(createLabel(\"Radar\"));\n" + + "rtlbPanel.add(createTextField(\"\"));\n" + + "rtlbPanel.add(createTextField(\"\"));\n" + + "\n" + + "// Left-to-right, Bottom-to-top\n" + + "MigLayout ltrbLM = new MigLayout(\"ltr,btt\",\n" + + " \"[][grow,fill]\",\n" + + " \"\");\n" + + "JPanel ltrbPanel = createTabPanel(ltrbLM);\n" + + "addSeparator(ltrbPanel, \"Left to Right, Bottom to Top\");\n" + + "ltrbPanel.add(createLabel(\"Level\"));\n" + + "ltrbPanel.add(createTextField(\"\"), \"span,growx\");\n" + + "ltrbPanel.add(createLabel(\"Radar\"));\n" + + "ltrbPanel.add(createTextField(\"\"));\n" + + "ltrbPanel.add(createTextField(\"\"));\n" + + "\n" + + "mainPanel.add(defPanel);\n" + + "mainPanel.add(rtlPanel);\n" + + "mainPanel.add(rtlbPanel);\n" + + "mainPanel.add(ltrbPanel);\n" + + "\n" + + "tabbedPane.addTab(\"Orientation\", mainPanel);"); + + return tabbedPane; + } + + public JComponent createCell_Position() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // Absolute grid position + MigLayout absLM = new MigLayout("", + "[100:pref,fill]", + "[100:pref,fill]"); + JPanel absPanel = createTabPanel(absLM); + absPanel.add(createButton(), "cell 0 0"); + absPanel.add(createButton(), "cell 2 0"); + absPanel.add(createButton(), "cell 3 0"); + absPanel.add(createButton(), "cell 1 1"); + absPanel.add(createButton(), "cell 0 2"); + absPanel.add(createButton(), "cell 2 2"); + absPanel.add(createButton(), "cell 2 2"); + + + // Relative grid position with wrap + MigLayout relAwLM = new MigLayout("wrap", + "[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]", + "[100:pref,fill]"); + JPanel relAwPanel = createTabPanel(relAwLM); + relAwPanel.add(createButton()); + relAwPanel.add(createButton(), "skip"); + relAwPanel.add(createButton()); + relAwPanel.add(createButton(), "skip,wrap"); + relAwPanel.add(createButton()); + relAwPanel.add(createButton(), "skip,split"); + relAwPanel.add(createButton()); + + + // Relative grid position with manual wrap + MigLayout relWLM = new MigLayout("", + "[100:pref,fill]", + "[100:pref,fill]"); + JPanel relWPanel = createTabPanel(relWLM); + relWPanel.add(createButton()); + relWPanel.add(createButton(), "skip"); + relWPanel.add(createButton(), "wrap"); + relWPanel.add(createButton(), "skip,wrap"); + relWPanel.add(createButton()); + relWPanel.add(createButton(), "skip,split"); + + relWPanel.add(createButton()); + + + // Mixed relative and absolute grid position + MigLayout mixLM = new MigLayout("", + "[100:pref,fill]", + "[100:pref,fill]"); + JPanel mixPanel = createTabPanel(mixLM); + mixPanel.add(createButton()); + mixPanel.add(createButton(), "cell 2 0"); + mixPanel.add(createButton()); + mixPanel.add(createButton(), "cell 1 1,wrap"); + mixPanel.add(createButton()); + mixPanel.add(createButton(), "cell 2 2,split"); + mixPanel.add(createButton()); + + tabbedPane.addTab("Absolute", absPanel); + tabbedPane.addTab("Relative + Wrap", relAwPanel); + tabbedPane.addTab("Relative", relWPanel); + tabbedPane.addTab("Mixed", mixPanel); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("\t\tJTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "\t\t// Absolute grid position\n" + + "\t\tMigLayout absLM = new MigLayout(\"\",\n" + + "\t\t \"[100:pref,fill]\",\n" + + "\t\t \"[100:pref,fill]\");\n" + + "\t\tJPanel absPanel = createTabPanel(absLM);\n" + + "\t\tabsPanel.add(createPanel(), \"cell 0 0\");\n" + + "\t\tabsPanel.add(createPanel(), \"cell 2 0\");\n" + + "\t\tabsPanel.add(createPanel(), \"cell 3 0\");\n" + + "\t\tabsPanel.add(createPanel(), \"cell 1 1\");\n" + + "\t\tabsPanel.add(createPanel(), \"cell 0 2\");\n" + + "\t\tabsPanel.add(createPanel(), \"cell 2 2\");\n" + + "\t\tabsPanel.add(createPanel(), \"cell 2 2\");\n" + + "\n" + + "\n" + + "\t\t// Relative grid position with wrap\n" + + "\t\tMigLayout relAwLM = new MigLayout(\"wrap\",\n" + + "\t\t \"[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]\",\n" + + "\t\t \"[100:pref,fill]\");\n" + + "\t\tJPanel relAwPanel = createTabPanel(relAwLM);\n" + + "\t\trelAwPanel.add(createPanel());\n" + + "\t\trelAwPanel.add(createPanel(), \"skip\");\n" + + "\t\trelAwPanel.add(createPanel());\n" + + "\t\trelAwPanel.add(createPanel(), \"skip,wrap\");\n" + + "\t\trelAwPanel.add(createPanel());\n" + + "\t\trelAwPanel.add(createPanel(), \"skip,split\");\n" + + "\t\trelAwPanel.add(createPanel());\n" + + "\n" + + "\n" + + "\t\t// Relative grid position with manual wrap\n" + + "\t\tMigLayout relWLM = new MigLayout(\"\",\n" + + "\t\t \"[100:pref,fill]\",\n" + + "\t\t \"[100:pref,fill]\");\n" + + "\t\tJPanel relWPanel = createTabPanel(relWLM);\n" + + "\t\trelWPanel.add(createPanel());\n" + + "\t\trelWPanel.add(createPanel(), \"skip\");\n" + + "\t\trelWPanel.add(createPanel(), \"wrap\");\n" + + "\t\trelWPanel.add(createPanel(), \"skip,wrap\");\n" + + "\t\trelWPanel.add(createPanel());\n" + + "\t\trelWPanel.add(createPanel(), \"skip,split\");\n" + + "\n" + + "\t\trelWPanel.add(createPanel());\n" + + "\n" + + "\n" + + "\t\t// Mixed relative and absolute grid position\n" + + "\t\tMigLayout mixLM = new MigLayout(\"\",\n" + + "\t\t \"[100:pref,fill]\",\n" + + "\t\t \"[100:pref,fill]\");\n" + + "\t\tJPanel mixPanel = createTabPanel(mixLM);\n" + + "\t\tmixPanel.add(createPanel());\n" + + "\t\tmixPanel.add(createPanel(), \"cell 2 0\");\n" + + "\t\tmixPanel.add(createPanel());\n" + + "\t\tmixPanel.add(createPanel(), \"cell 1 1,wrap\");\n" + + "\t\tmixPanel.add(createPanel());\n" + + "\t\tmixPanel.add(createPanel(), \"cell 2 2,split\");\n" + + "\t\tmixPanel.add(createPanel());\n" + + "\n" + + "\t\ttabbedPane.addTab(\"Absolute\", absPanel);\n" + + "\t\ttabbedPane.addTab(\"Relative + Wrap\", relAwPanel);\n" + + "\t\ttabbedPane.addTab(\"Relative\", relWPanel);\n" + + "\t\ttabbedPane.addTab(\"Mixed\", mixPanel);"); + + return tabbedPane; + } + + public JComponent createPlain() + { + return createPlainImpl(false); + } + + private JComponent createPlainImpl(boolean debug) + { + JTabbedPane tabbedPane = new JTabbedPane(); + + MigLayout lm = new MigLayout((debug && benchRuns == 0 ? "debug, inset 20" : "ins 20"), "[para]0[][100lp, fill][60lp][95lp, fill]", ""); + JPanel panel = createTabPanel(lm); + + addSeparator(panel, "Manufacturer"); + + panel.add(createLabel("Company"), "skip"); + panel.add(createTextField(""), "span, growx"); + panel.add(createLabel("Contact"), "skip"); + panel.add(createTextField(""), "span, growx"); + panel.add(createLabel("Order No"), "skip"); + panel.add(createTextField(15), "wrap para"); + + addSeparator(panel, "Inspector"); + + panel.add(createLabel("Name"), "skip"); + panel.add(createTextField(""), "span, growx"); + panel.add(createLabel("Reference No"), "skip"); + panel.add(createTextField(""), "wrap"); + panel.add(createLabel("Status"), "skip"); + panel.add(createCombo(new String[] {"In Progress", "Finnished", "Released"}), "wrap para"); + + addSeparator(panel, "Ship"); + + panel.add(createLabel("Shipyard"), "skip"); + panel.add(createTextField(""), "span, growx"); + panel.add(createLabel("Register No"), "skip"); + panel.add(createTextField("")); + panel.add(createLabel("Hull No"), "right"); + panel.add(createTextField(15), "wrap"); + panel.add(createLabel("Project Type"), "skip"); + panel.add(createCombo(new String[] {"New Building", "Convention", "Repair"})); + + if (debug) + panel.add(createLabel("Red is cell bounds. Blue is component bounds."), "newline,ax left,span,gaptop 40,"); + + tabbedPane.addTab("Plain", panel); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "MigLayout lm = new MigLayout((debug && benchRuns == 0 ? \"debug, inset 20\" : \"ins 20\"), \"[para]0[][100lp, fill][60lp][95lp, fill]\", \"\");\n" + + "JPanel panel = createTabPanel(lm);\n" + + "\n" + + "addSeparator(panel, \"Manufacturer\");\n" + + "\n" + + "panel.add(createLabel(\"Company\"), \"skip\");\n" + + "panel.add(createTextField(\"\"), \"span, growx\");\n" + + "panel.add(createLabel(\"Contact\"), \"skip\");\n" + + "panel.add(createTextField(\"\"), \"span, growx\");\n" + + "panel.add(createLabel(\"Order No\"), \"skip\");\n" + + "panel.add(createTextField(15), \"wrap para\");\n" + + "\n" + + "addSeparator(panel, \"Inspector\");\n" + + "\n" + + "panel.add(createLabel(\"Name\"), \"skip\");\n" + + "panel.add(createTextField(\"\"), \"span, growx\");\n" + + "panel.add(createLabel(\"Reference No\"), \"skip\");\n" + + "panel.add(createTextField(\"\"), \"wrap\");\n" + + "panel.add(createLabel(\"Status\"), \"skip\");\n" + + "panel.add(createCombo(new String[] {\"In Progress\", \"Finnished\", \"Released\"}), \"wrap para\");\n" + + "\n" + + "addSeparator(panel, \"Ship\");\n" + + "\n" + + "panel.add(createLabel(\"Shipyard\"), \"skip\");\n" + + "panel.add(createTextField(\"\"), \"span, growx\");\n" + + "panel.add(createLabel(\"Register No\"), \"skip\");\n" + + "panel.add(createTextField(\"\"));\n" + + "panel.add(createLabel(\"Hull No\"), \"right\");\n" + + "panel.add(createTextField(15), \"wrap\");\n" + + "panel.add(createLabel(\"Project Type\"), \"skip\");\n" + + "panel.add(createCombo(new String[] {\"New Building\", \"Convention\", \"Repair\"}));\n" + + "\n" + + "if (debug)\n" + + "\tpanel.add(createLabel(\"Red is cell bounds. Blue is component bounds.\"), \"newline,ax left,span,gaptop 40,\");\n" + + "\n" + + "tabbedPane.addTab(\"Plain\", panel);"); + + return tabbedPane; + } + + public JComponent createBound_Sizes() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1 + String colConstr = i == 0 ? "[right][200]" : "[right, 75lp:pref][200]"; + + MigLayout LM1 = new MigLayout("wrap", colConstr, ""); + JPanel panel1 = createTabPanel(LM1); + panel1.add(createLabel("File Number:")); + panel1.add(createTextField(""), "growx"); + panel1.add(createLabel("RFQ Number:")); + panel1.add(createTextField(""), "growx"); + panel1.add(createLabel("Entry Date:")); + panel1.add(createTextField(6)); + panel1.add(createLabel("Sales Person:")); + panel1.add(createTextField(""), "growx"); + + MigLayout LM2 = new MigLayout("wrap", colConstr, ""); + JPanel panel2 = createTabPanel(LM2); + panel2.add(createLabel("Shipper:")); + panel2.add(createTextField(6), "split 2"); + panel2.add(createTextField(""), "growx"); + panel2.add(createLabel("Consignee:")); + panel2.add(createTextField(6), "split 2"); + panel2.add(createTextField(""), "growx"); + panel2.add(createLabel("Departure:")); + panel2.add(createTextField(6), "split 2"); + panel2.add(createTextField(""), "growx"); + panel2.add(createLabel("Destination:")); + panel2.add(createTextField(6), "split 2"); + panel2.add(createTextField(""), "growx"); + + tabbedPane.addTab(i == 0 ? "Jumping 1" : "Stable 1", panel1); + tabbedPane.addTab(i == 0 ? "Jumping 2" : "Stable 2", panel2); + } + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1\n" + + "\tString colConstr = i == 0 ? \"[right][200]\" : \"[right, 75lp:pref][200]\";\n" + + "\n" + + "\tMigLayout LM1 = new MigLayout(\"wrap\", colConstr, \"\");\n" + + "\tJPanel panel1 = createTabPanel(LM1);\n" + + "\tpanel1.add(createLabel(\"File Number:\"));\n" + + "\tpanel1.add(createTextField(\"\"), \"growx\");\n" + + "\tpanel1.add(createLabel(\"RFQ Number:\"));\n" + + "\tpanel1.add(createTextField(\"\"), \"growx\");\n" + + "\tpanel1.add(createLabel(\"Entry Date:\"));\n" + + "\tpanel1.add(createTextField(6));\n" + + "\tpanel1.add(createLabel(\"Sales Person:\"));\n" + + "\tpanel1.add(createTextField(\"\"), \"growx\");\n" + + "\n" + + "\tMigLayout LM2 = new MigLayout(\"wrap\", colConstr, \"\");\n" + + "\tJPanel panel2 = createTabPanel(LM2);\n" + + "\tpanel2.add(createLabel(\"Shipper:\"));\n" + + "\tpanel2.add(createTextField(6), \"split 2\");\n" + + "\tpanel2.add(createTextField(\"\"), \"growx\");\n" + + "\tpanel2.add(createLabel(\"Consignee:\"));\n" + + "\tpanel2.add(createTextField(6), \"split 2\");\n" + + "\tpanel2.add(createTextField(\"\"), \"growx\");\n" + + "\tpanel2.add(createLabel(\"Departure:\"));\n" + + "\tpanel2.add(createTextField(6), \"split 2\");\n" + + "\tpanel2.add(createTextField(\"\"), \"growx\");\n" + + "\tpanel2.add(createLabel(\"Destination:\"));\n" + + "\tpanel2.add(createTextField(6), \"split 2\");\n" + + "\tpanel2.add(createTextField(\"\"), \"growx\");\n" + + "\n" + + "\ttabbedPane.addTab(i == 0 ? \"Jumping 1\" : \"Stable 2\", panel1);\n" + + "\ttabbedPane.addTab(i == 0 ? \"Jumping 2\" : \"Stable 2\", panel2);\n" + + "}"); + + return tabbedPane; + } + + public JComponent createComponent_Sizes() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + MigLayout LM = new MigLayout("wrap", "[right][0:pref,grow]", ""); + + JPanel panel = createTabPanel(LM); + JScrollPane descrText = createTextAreaScroll("Use slider to see how the components grow and shrink depending on the constraints set on them.", 0, 0, false); + + descrText.setOpaque(OPAQUE); + descrText.setBorder(new EmptyBorder(10, 10, 10, 10)); + ((JTextArea) descrText.getViewport().getView()).setOpaque(OPAQUE); + descrText.getViewport().setOpaque(OPAQUE); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panel, descrText); + splitPane.setOpaque(OPAQUE); + splitPane.setBorder(null); + + panel.add(createLabel("\"\"")); + panel.add(createTextField("8")); + panel.add(createLabel("\"min!\"")); + panel.add(createTextField("3", 3), "width min!"); + panel.add(createLabel("\"pref!\"")); + panel.add(createTextField("3", 3), "width pref!"); + panel.add(createLabel("\"min:pref\"")); + panel.add(createTextField("8", 8), "width min:pref"); + panel.add(createLabel("\"min:100:150\"")); + panel.add(createTextField("8", 8), "width min:100:150"); + panel.add(createLabel("\"min:100:150, growx\"")); + panel.add(createTextField("8", 8), "width min:100:150, growx"); + panel.add(createLabel("\"min:100, growx\"")); + panel.add(createTextField("8", 8), "width min:100, growx"); + panel.add(createLabel("\"40!\"")); + panel.add(createTextField("8", 8), "width 40!"); + panel.add(createLabel("\"40:40:40\"")); + panel.add(createTextField("8", 8), "width 40:40:40"); + + tabbedPane.addTab("Component Sizes", splitPane); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "MigLayout LM = new MigLayout(\"wrap\", \"[right][0:pref,grow]\", \"\");\n" + + "\n" + + "JPanel panel = createTabPanel(LM);\n" + + "JScrollPane descrText = createTextAreaScroll(\"Use slider to see how the components grow and shrink depending on the constraints set on them.\", 0, 0, false);\n" + + "\n" + + "descrText.setOpaque(OPAQUE);\n" + + "descrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" + + "((JTextArea) descrText.getViewport().getView()).setOpaque(OPAQUE);\n" + + "descrText.getViewport().setOpaque(OPAQUE);\n" + + "\n" + + "JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panel, descrText);\n" + + "splitPane.setOpaque(OPAQUE);\n" + + "splitPane.setBorder(null);\n" + + "\n" + + "panel.add(createLabel(\"\\\"\\\"\"));\n" + + "panel.add(createTextField(\"8\", 8));\n" + + "panel.add(createLabel(\"\\\"min!\\\"\"));\n" + + "panel.add(createTextField(\"3\", 3), \"width min!\");\n" + + "panel.add(createLabel(\"\\\"pref!\\\"\"));\n" + + "panel.add(createTextField(\"3\", 3), \"width pref!\");\n" + + "panel.add(createLabel(\"\\\"min:pref\\\"\"));\n" + + "panel.add(createTextField(\"8\", 8), \"width min:pref\");\n" + + "panel.add(createLabel(\"\\\"min:100:150\\\"\"));\n" + + "panel.add(createTextField(\"8\", 8), \"width min:100:150\");\n" + + "panel.add(createLabel(\"\\\"min:100:150, growx\\\"\"));\n" + + "panel.add(createTextField(\"8\", 8), \"width min:100:150, growx\");\n" + + "panel.add(createLabel(\"\\\"min:100, growx\\\"\"));\n" + + "panel.add(createTextField(\"8\", 8), \"width min:100, growx\");\n" + + "panel.add(createLabel(\"\\\"40!\\\"\"));\n" + + "panel.add(createTextField(\"8\", 8), \"width 40!\");\n" + + "panel.add(createLabel(\"\\\"40:40:40\\\"\"));\n" + + "panel.add(createTextField(\"8\", 8), \"width 40:40:40\");\n" + + "\n" + + "tabbedPane.addTab(\"Component Sizes\", splitPane);"); + + return tabbedPane; + } + + public JComponent createCell_Alignments() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // Horizontal + MigLayout hLM = new MigLayout("wrap", + "[grow,left][grow,center][grow,right][grow,fill,center]", + "[]unrel[][]"); + JPanel hPanel = createTabPanel(hLM); + String[] sizes = new String[] {"", "growx", "growx 0", "left", "center", "right", "leading", "trailing"}; + hPanel.add(createLabel("[left]"), "c"); + hPanel.add(createLabel("[center]"), "c"); + hPanel.add(createLabel("[right]"), "c"); + hPanel.add(createLabel("[fill,center]"), "c, growx 0"); + + for (int r = 0; r < sizes.length; r++) { + for (int c = 0; c < 4; c++) { + String text = sizes[r].length() > 0 ? sizes[r] : "default"; + hPanel.add(createButton(text), sizes[r]); + } + } + + // Vertical + MigLayout vLM = new MigLayout("wrap,flowy", + "[right][]", + "[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]"); + JPanel vPanel = createTabPanel(vLM); + String[] vSizes = new String[] {"", "growy", "growy 0", "top", "center", "bottom"}; + vPanel.add(createLabel("[top]"), "center"); + vPanel.add(createLabel("[center]"), "center"); + vPanel.add(createLabel("[bottom]"), "center"); + vPanel.add(createLabel("[fill, bottom]"), "center, growy 0"); + vPanel.add(createLabel("[fill, baseline]"), "center"); + + for (int c = 0; c < vSizes.length; c++) { + for (int r = 0; r < 5; r++) { + String text = vSizes[c].length() > 0 ? vSizes[c] : "default"; + JButton b = createButton(text); + if (r == 4 && c <= 1) + b.setFont(new Font("sansserif", Font.PLAIN, 16 + c * 5)); + vPanel.add(b, vSizes[c]); + } + } + + tabbedPane.addTab("Horizontal", hPanel); + tabbedPane.addTab("Vertical", vPanel); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// Horizontal\n" + + "MigLayout hLM = new MigLayout(\"wrap\",\n" + + " \"[grow,left][grow,center][grow,right][grow,fill,center]\",\n" + + " \"[]unrel[][]\");\n" + + "JPanel hPanel = createTabPanel(hLM);\n" + + "String[] sizes = new String[] {\"\", \"growx\", \"growx 0\", \"left\", \"center\", \"right\", \"leading\", \"trailing\"};\n" + + "hPanel.add(createLabel(\"[left]\"), \"c\");\n" + + "hPanel.add(createLabel(\"[center]\"), \"c\");\n" + + "hPanel.add(createLabel(\"[right]\"), \"c\");\n" + + "hPanel.add(createLabel(\"[fill,center]\"), \"c, growx 0\");\n" + + "\n" + + "for (int r = 0; r < sizes.length; r++) {\n" + + "\tfor (int c = 0; c < 4; c++) {\n" + + "\t\tString text = sizes[r].length() > 0 ? sizes[r] : \"default\";\n" + + "\t\thPanel.add(createButton(text), sizes[r]);\n" + + "\t}\n" + + "}\n" + + "\n" + + "// Vertical\n" + + "MigLayout vLM = new MigLayout(\"wrap,flowy\",\n" + + " \"[right][]\",\n" + + " \"[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]\");\n" + + "JPanel vPanel = createTabPanel(vLM);\n" + + "String[] vSizes = new String[] {\"\", \"growy\", \"growy 0\", \"top\", \"center\", \"bottom\"};\n" + + "vPanel.add(createLabel(\"[top]\"), \"center\");\n" + + "vPanel.add(createLabel(\"[center]\"), \"center\");\n" + + "vPanel.add(createLabel(\"[bottom]\"), \"center\");\n" + + "vPanel.add(createLabel(\"[fill, bottom]\"), \"center, growy 0\");\n" + + "vPanel.add(createLabel(\"[fill, baseline]\"), \"center\");\n" + + "\n" + + "for (int c = 0; c < vSizes.length; c++) {\n" + + "\tfor (int r = 0; r < 5; r++) {\n" + + "\t\tString text = vSizes[c].length() > 0 ? vSizes[c] : \"default\";\n" + + "\t\tJButton b = createButton(text);\n" + + "\t\tif (r == 4 && c <= 1)\n" + + "\t\t\tb.setFont(new Font(\"sansserif\", Font.PLAIN, 16 + c * 5));\n" + + "\t\tvPanel.add(b, vSizes[c]);\n" + + "\t}\n" + + "}\n" + + "\n" + + "tabbedPane.addTab(\"Horizontal\", hPanel);\n" + + "tabbedPane.addTab(\"Vertical\", vPanel);"); + + return tabbedPane; + } + + public JComponent createUnits() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // Horizontal + MigLayout hLM = new MigLayout("wrap,nocache", + "[right][]", + ""); + JPanel hPanel = createTabPanel(hLM); + String[] sizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "20sp"}; + for (int i = 0; i < sizes.length; i++) { + hPanel.add(createLabel(sizes[i])); + hPanel.add(createTextField(""), "width " + sizes[i] + "!"); + } + + // Horizontal lp + MigLayout hlpLM = new MigLayout("nocache", "[right][][]", ""); + JPanel hlpPanel = createTabPanel(hlpLM); + hlpPanel.add(createLabel("9 cols")); + hlpPanel.add(createTextField(9)); + String[] lpSizes = new String[] {"75lp", "75px", "88px", "100px"}; + hlpPanel.add(createLabel("Width of createTextField(9)"), "wrap"); + for (int i = 0; i < lpSizes.length; i++) { + hlpPanel.add(createLabel(lpSizes[i])); + hlpPanel.add(createTextField(""), "width " + lpSizes[i] + "!, wrap"); + } + + // Vertical + MigLayout vLM = new MigLayout("wrap,flowy,nocache", + "[c]", + "[top][top]"); + JPanel vPanel = createTabPanel(vLM); + String[] vSizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "20sp"}; + for (int i = 0; i < sizes.length; i++) { + vPanel.add(createLabel(vSizes[i])); + vPanel.add(createTextArea("", 0, 5), "width 50!, height " + vSizes[i] + "!"); + } + + // Vertical lp + MigLayout vlpLM = new MigLayout("wrap,flowy,nocache", + "[c]", + "[top][top]40px[top][top]"); + JPanel vlpPanel = createTabPanel(vlpLM); + vlpPanel.add(createLabel("4 rows")); + vlpPanel.add(createTextArea("", 4, 5), "width 50!"); + vlpPanel.add(createLabel("field")); + vlpPanel.add(createTextField(5)); + + String[] vlpSizes1 = new String[] {"63lp", "57px", "63px", "68px", "25%"}; + String[] vlpSizes2 = new String[] {"21lp", "21px", "23px", "24px", "10%"}; + for (int i = 0; i < vlpSizes1.length; i++) { + vlpPanel.add(createLabel(vlpSizes1[i])); + vlpPanel.add(createTextArea("", 1, 5), "width 50!, height " + vlpSizes1[i] + "!"); + vlpPanel.add(createLabel(vlpSizes2[i])); + vlpPanel.add(createTextField(5), "height " + vlpSizes2[i] + "!"); + } + + vlpPanel.add(createLabel("button"), "skip 2"); + vlpPanel.add(createButton("...")); + + tabbedPane.addTab("Horizontal", hPanel); + tabbedPane.addTab("Horizontal LP", hlpPanel); + tabbedPane.addTab("Vertical", vPanel); + tabbedPane.addTab("Vertical LP", vlpPanel); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// Horizontal\n" + + "MigLayout hLM = new MigLayout(\"wrap,nocache\",\n" + + "\t\t\t\t\t\t\t \"[right][]\",\n" + + "\t\t\t\t\t\t\t \"\");\n" + + "JPanel hPanel = createTabPanel(hLM);\n" + + "String[] sizes = new String[] {\"72pt\", \"25.4mm\", \"2.54cm\", \"1in\", \"72px\", \"96px\", \"120px\", \"25%\", \"20sp\"};\n" + + "for (int i = 0; i < sizes.length; i++) {\n" + + "\thPanel.add(createLabel(sizes[i]));\n" + + "\thPanel.add(createTextField(\"\"), \"width \" + sizes[i] + \"!\");\n" + + "}\n" + + "\n" + + "// Horizontal lp\n" + + "MigLayout hlpLM = new MigLayout(\"nocache\", \"[right][][]\", \"\");\n" + + "JPanel hlpPanel = createTabPanel(hlpLM);\n" + + "hlpPanel.add(createLabel(\"9 cols\"));\n" + + "hlpPanel.add(createTextField(9));\n" + + "String[] lpSizes = new String[] {\"75lp\", \"75px\", \"88px\", \"100px\"};\n" + + "hlpPanel.add(createLabel(\"Width of createTextField(9)\"), \"wrap\");\n" + + "for (int i = 0; i < lpSizes.length; i++) {\n" + + "\thlpPanel.add(createLabel(lpSizes[i]));\n" + + "\thlpPanel.add(createTextField(\"\"), \"width \" + lpSizes[i] + \"!, wrap\");\n" + + "}\n" + + "\n" + + "// Vertical\n" + + "MigLayout vLM = new MigLayout(\"wrap,flowy,nocache\",\n" + + "\t\t\t\t\t\t\t \"[c]\",\n" + + "\t\t\t\t\t\t\t \"[top][top]\");\n" + + "JPanel vPanel = createTabPanel(vLM);\n" + + "String[] vSizes = new String[] {\"72pt\", \"25.4mm\", \"2.54cm\", \"1in\", \"72px\", \"96px\", \"120px\", \"25%\", \"20sp\"};\n" + + "for (int i = 0; i < sizes.length; i++) {\n" + + "\tvPanel.add(createLabel(vSizes[i]));\n" + + "\tvPanel.add(createTextArea(\"\", 0, 5), \"width 50!, height \" + vSizes[i] + \"!\");\n" + + "}\n" + + "\n" + + "// Vertical lp\n" + + "MigLayout vlpLM = new MigLayout(\"wrap,flowy,nocache\",\n" + + "\t\t\t\t\t\t\t\t\"[c]\",\n" + + "\t\t\t\t\t\t\t\t\"[top][top]40px[top][top]\");\n" + + "JPanel vlpPanel = createTabPanel(vlpLM);\n" + + "vlpPanel.add(createLabel(\"4 rows\"));\n" + + "vlpPanel.add(createTextArea(\"\", 4, 5), \"width 50!\");\n" + + "vlpPanel.add(createLabel(\"field\"));\n" + + "vlpPanel.add(createTextField(5));\n" + + "\n" + + "String[] vlpSizes1 = new String[] {\"63lp\", \"57px\", \"63px\", \"68px\", \"25%\"};\n" + + "String[] vlpSizes2 = new String[] {\"21lp\", \"21px\", \"23px\", \"24px\", \"10%\"};\n" + + "for (int i = 0; i < vlpSizes1.length; i++) {\n" + + "\tvlpPanel.add(createLabel(vlpSizes1[i]));\n" + + "\tvlpPanel.add(createTextArea(\"\", 1, 5), \"width 50!, height \" + vlpSizes1[i] + \"!\");\n" + + "\tvlpPanel.add(createLabel(vlpSizes2[i]));\n" + + "\tvlpPanel.add(createTextField(5), \"height \" + vlpSizes2[i] + \"!\");\n" + + "}\n" + + "\n" + + "vlpPanel.add(createLabel(\"button\"), \"skip 2\");\n" + + "vlpPanel.add(createButton(\"...\"));\n" + + "\n" + + "tabbedPane.addTab(\"Horizontal\", hPanel);\n" + + "tabbedPane.addTab(\"Horizontal LP\", hlpPanel);\n" + + "tabbedPane.addTab(\"Vertical\", vPanel);\n" + + "tabbedPane.addTab(\"Vertical LP\", vlpPanel);"); + + return tabbedPane; + } + + public JComponent createGrouping() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // Ungrouped + MigLayout ugM = new MigLayout("", "[]push[][][]", ""); + JPanel ugPanel = createTabPanel(ugM); + ugPanel.add(createButton("Help")); + ugPanel.add(createButton("< Back"), ""); + ugPanel.add(createButton("Forward >"), "gap push"); + ugPanel.add(createButton("Apply"), "gap unrel"); + ugPanel.add(createButton("Cancel"), "gap unrel"); + + // Grouped Components + MigLayout gM = new MigLayout("nogrid, fillx"); + JPanel gPanel = createTabPanel(gM); + gPanel.add(createButton("Help"), "sg"); + gPanel.add(createButton("< Back"), "sg,gap push"); + gPanel.add(createButton("Forward >"), "sg"); + gPanel.add(createButton("Apply"), "sg,gap unrel"); + gPanel.add(createButton("Cancel"), "sg,gap unrel"); + + // Grouped Columns + MigLayout gcM = new MigLayout("", "[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]", ""); + JPanel gcPanel = createTabPanel(gcM); + gcPanel.add(createButton("Help")); + gcPanel.add(createButton("< Back")); + gcPanel.add(createButton("Forward >")); + gcPanel.add(createButton("Apply")); + gcPanel.add(createButton("Cancel")); + + // Ungrouped Rows + MigLayout ugrM = new MigLayout(); // no "sg" is the only difference to next panel + JPanel ugrPanel = createTabPanel(ugrM); + ugrPanel.add(createLabel("File Number:")); + ugrPanel.add(createTextField(30), "wrap"); + ugrPanel.add(createLabel("BL/MBL number:")); + ugrPanel.add(createTextField(7), "split 2"); + ugrPanel.add(createTextField(7), "wrap"); + ugrPanel.add(createLabel("Entry Date:")); + ugrPanel.add(createTextField(7), "wrap"); + ugrPanel.add(createLabel("RFQ Number:")); + ugrPanel.add(createTextField(30), "wrap"); + ugrPanel.add(createLabel("Goods:")); + ugrPanel.add(createCheck("Dangerous"), "wrap"); + ugrPanel.add(createLabel("Shipper:")); + ugrPanel.add(createTextField(30), "wrap"); + ugrPanel.add(createLabel("Customer:")); + ugrPanel.add(createTextField(""), "split 2,growx"); + ugrPanel.add(createButton("..."), "width 60px:pref,wrap"); + ugrPanel.add(createLabel("Port of Loading:")); + ugrPanel.add(createTextField(30), "wrap"); + ugrPanel.add(createLabel("Destination:")); + ugrPanel.add(createTextField(30), "wrap"); + + // Grouped Rows + MigLayout grM = new MigLayout("", "[]", "[sg]"); // "sg" is the only difference to previous panel + JPanel grPanel = createTabPanel(grM); + grPanel.add(createLabel("File Number:")); + grPanel.add(createTextField(30),"wrap"); + grPanel.add(createLabel("BL/MBL number:")); + grPanel.add(createTextField(7),"split 2"); + grPanel.add(createTextField(7), "wrap"); + grPanel.add(createLabel("Entry Date:")); + grPanel.add(createTextField(7), "wrap"); + grPanel.add(createLabel("RFQ Number:")); + grPanel.add(createTextField(30), "wrap"); + grPanel.add(createLabel("Goods:")); + grPanel.add(createCheck("Dangerous"), "wrap"); + grPanel.add(createLabel("Shipper:")); + grPanel.add(createTextField(30), "wrap"); + grPanel.add(createLabel("Customer:")); + grPanel.add(createTextField(""), "split 2,growx"); + grPanel.add(createButton("..."), "width 50px:pref,wrap"); + grPanel.add(createLabel("Port of Loading:")); + grPanel.add(createTextField(30), "wrap"); + grPanel.add(createLabel("Destination:")); + grPanel.add(createTextField(30), "wrap"); + + tabbedPane.addTab("Ungrouped", ugPanel); + tabbedPane.addTab("Grouped (Components)", gPanel); + tabbedPane.addTab("Grouped (Columns)", gcPanel); + tabbedPane.addTab("Ungrouped Rows", ugrPanel); + tabbedPane.addTab("Grouped Rows", grPanel); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// Ungrouped\n" + + "MigLayout ugM = new MigLayout(\"\", \"[]push[][][]\", \"\");\n" + + "JPanel ugPanel = createTabPanel(ugM);\n" + + "ugPanel.add(createButton(\"Help\"));\n" + + "ugPanel.add(createButton(\"< Back\"), \"\");\n" + + "ugPanel.add(createButton(\"Forward >\"), \"gap push\");\n" + + "ugPanel.add(createButton(\"Apply\"), \"gap unrel\");\n" + + "ugPanel.add(createButton(\"Cancel\"), \"gap unrel\");\n" + + "\n" + + "// Grouped Components\n" + + "MigLayout gM = new MigLayout(\"nogrid, fillx\");\n" + + "JPanel gPanel = createTabPanel(gM);\n" + + "gPanel.add(createButton(\"Help\"), \"sg\");\n" + + "gPanel.add(createButton(\"< Back\"), \"sg,gap push\");\n" + + "gPanel.add(createButton(\"Forward >\"), \"sg\");\n" + + "gPanel.add(createButton(\"Apply\"), \"sg,gap unrel\");\n" + + "gPanel.add(createButton(\"Cancel\"), \"sg,gap unrel\");\n" + + "\n" + + "// Grouped Columns\n" + + "MigLayout gcM = new MigLayout(\"\", \"[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]\", \"\");\n" + + "JPanel gcPanel = createTabPanel(gcM);\n" + + "gcPanel.add(createButton(\"Help\"));\n" + + "gcPanel.add(createButton(\"< Back\"));\n" + + "gcPanel.add(createButton(\"Forward >\"));\n" + + "gcPanel.add(createButton(\"Apply\"));\n" + + "gcPanel.add(createButton(\"Cancel\"));\n" + + "\n" + + "// Ungrouped Rows\n" + + "MigLayout ugrM = new MigLayout(); // no \"sg\" is the only difference to next panel\n" + + "JPanel ugrPanel = createTabPanel(ugrM);\n" + + "ugrPanel.add(createLabel(\"File Number:\"));\n" + + "ugrPanel.add(createTextField(30), \"wrap\");\n" + + "ugrPanel.add(createLabel(\"BL/MBL number:\"));\n" + + "ugrPanel.add(createTextField(7), \"split 2\");\n" + + "ugrPanel.add(createTextField(7), \"wrap\");\n" + + "ugrPanel.add(createLabel(\"Entry Date:\"));\n" + + "ugrPanel.add(createTextField(7), \"wrap\");\n" + + "ugrPanel.add(createLabel(\"RFQ Number:\"));\n" + + "ugrPanel.add(createTextField(30), \"wrap\");\n" + + "ugrPanel.add(createLabel(\"Goods:\"));\n" + + "ugrPanel.add(createCheck(\"Dangerous\"), \"wrap\");\n" + + "ugrPanel.add(createLabel(\"Shipper:\"));\n" + + "ugrPanel.add(createTextField(30), \"wrap\");\n" + + "ugrPanel.add(createLabel(\"Customer:\"));\n" + + "ugrPanel.add(createTextField(\"\"), \"split 2,growx\");\n" + + "ugrPanel.add(createButton(\"...\"), \"width 60px:pref,wrap\");\n" + + "ugrPanel.add(createLabel(\"Port of Loading:\"));\n" + + "ugrPanel.add(createTextField(30), \"wrap\");\n" + + "ugrPanel.add(createLabel(\"Destination:\"));\n" + + "ugrPanel.add(createTextField(30), \"wrap\");\n" + + "\n" + + "// Grouped Rows\n" + + "MigLayout grM = new MigLayout(\"\", \"[]\", \"[sg]\"); // \"sg\" is the only difference to previous panel\n" + + "JPanel grPanel = createTabPanel(grM);\n" + + "grPanel.add(createLabel(\"File Number:\"));\n" + + "grPanel.add(createTextField(30),\"wrap\");\n" + + "grPanel.add(createLabel(\"BL/MBL number:\"));\n" + + "grPanel.add(createTextField(7),\"split 2\");\n" + + "grPanel.add(createTextField(7), \"wrap\");\n" + + "grPanel.add(createLabel(\"Entry Date:\"));\n" + + "grPanel.add(createTextField(7), \"wrap\");\n" + + "grPanel.add(createLabel(\"RFQ Number:\"));\n" + + "grPanel.add(createTextField(30), \"wrap\");\n" + + "grPanel.add(createLabel(\"Goods:\"));\n" + + "grPanel.add(createCheck(\"Dangerous\"), \"wrap\");\n" + + "grPanel.add(createLabel(\"Shipper:\"));\n" + + "grPanel.add(createTextField(30), \"wrap\");\n" + + "grPanel.add(createLabel(\"Customer:\"));\n" + + "grPanel.add(createTextField(\"\"), \"split 2,growx\");\n" + + "grPanel.add(createButton(\"...\"), \"width 50px:pref,wrap\");\n" + + "grPanel.add(createLabel(\"Port of Loading:\"));\n" + + "grPanel.add(createTextField(30), \"wrap\");\n" + + "grPanel.add(createLabel(\"Destination:\"));\n" + + "grPanel.add(createTextField(30), \"wrap\");\n" + + "\n" + + "tabbedPane.addTab(\"Ungrouped\", ugPanel);\n" + + "tabbedPane.addTab(\"Grouped (Components)\", gPanel);\n" + + "tabbedPane.addTab(\"Grouped (Columns)\", gcPanel);\n" + + "tabbedPane.addTab(\"Ungrouped Rows\", ugrPanel);\n" + + "tabbedPane.addTab(\"Grouped Rows\", grPanel);"); + + return tabbedPane; + } + + public JComponent createSpan() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // Horizontal span + MigLayout colLM = new MigLayout("nocache", + "[fill][25%!,fill][105lp!,fill][100px!,fill]", + "[]15[][]"); + JPanel colPanel = createTabPanel(colLM); + colPanel.add(createTextField("Col1 [ ]")); + colPanel.add(createTextField("Col2 [25%!]")); + colPanel.add(createTextField("Col3 [105lp!]")); + colPanel.add(createTextField("Col4 [100px!]"), "wrap"); + + colPanel.add(createLabel("Full Name:")); + colPanel.add(createTextField("span, growx", 40), "span,growx"); + + colPanel.add(createLabel("Phone:")); + colPanel.add(createTextField(5), "span 3, split 5"); + colPanel.add(createTextField(7)); + colPanel.add(createTextField(7)); + colPanel.add(createTextField(9)); + colPanel.add(createLabel("(span 3, split 4)"), "wrap"); + + colPanel.add(createLabel("Zip/City:")); + colPanel.add(createTextField(5)); + colPanel.add(createTextField("span 2, growx", 5), "span 2,growx"); + + // Vertical span + MigLayout rowLM = new MigLayout("wrap", + "[225lp]para[225lp]", + "[]3[]unrel[]3[]unrel[]3[]"); + JPanel rowPanel = createTabPanel(rowLM); + rowPanel.add(createLabel("Name")); + rowPanel.add(createLabel("Notes")); + rowPanel.add(createTextField("growx"), "growx"); + rowPanel.add(createTextArea("spany,grow", 5, 20), "spany,grow"); + rowPanel.add(createLabel("Phone")); + rowPanel.add(createTextField("growx"), "growx"); + rowPanel.add(createLabel("Fax")); + rowPanel.add(createTextField("growx"), "growx"); + + tabbedPane.addTab("Column Span/Split", colPanel); + tabbedPane.addTab("Row Span", rowPanel); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("\t\tJTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "\t\t// Horizontal span\n" + + "\t\tMigLayout colLM = new MigLayout(\"\",\n" + + "\t\t \"[fill][25%!,fill][105lp!,fill][100px!,fill]\",\n" + + "\t\t \"[]15[][]\");\n" + + "\t\tJPanel colPanel = createTabPanel(colLM);\n" + + "\t\tcolPanel.add(createTextField(\"Col1 [ ]\"));\n" + + "\t\tcolPanel.add(createTextField(\"Col2 [25%!]\"));\n" + + "\t\tcolPanel.add(createTextField(\"Col3 [105lp!]\"));\n" + + "\t\tcolPanel.add(createTextField(\"Col4 [100px!]\"), \"wrap\");\n" + + "\n" + + "\t\tcolPanel.add(createLabel(\"Full Name:\"));\n" + + "\t\tcolPanel.add(createTextField(\"span, growx\", 40), \"span,growx\");\n" + + "\n" + + "\t\tcolPanel.add(createLabel(\"Phone:\"));\n" + + "\t\tcolPanel.add(createTextField(5), \"span 3, split 5\");\n" + + "\t\tcolPanel.add(createTextField(7));\n" + + "\t\tcolPanel.add(createTextField(7));\n" + + "\t\tcolPanel.add(createTextField(9));\n" + + "\t\tcolPanel.add(createLabel(\"(span 3, split 4)\"), \"wrap\");\n" + + "\n" + + "\t\tcolPanel.add(createLabel(\"Zip/City:\"));\n" + + "\t\tcolPanel.add(createTextField(5));\n" + + "\t\tcolPanel.add(createTextField(\"span 2, growx\", 5), \"span 2,growx\");\n" + + "\n" + + "\t\t// Vertical span\n" + + "\t\tMigLayout rowLM = new MigLayout(\"wrap\",\n" + + "\t\t \"[225lp]para[225lp]\",\n" + + "\t\t \"[]3[]unrel[]3[]unrel[]3[]\");\n" + + "\t\tJPanel rowPanel = createTabPanel(rowLM);\n" + + "\t\trowPanel.add(createLabel(\"Name\"));\n" + + "\t\trowPanel.add(createLabel(\"Notes\"));\n" + + "\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" + + "\t\trowPanel.add(createTextArea(\"spany,grow\", 5, 20), \"spany,grow\");\n" + + "\t\trowPanel.add(createLabel(\"Phone\"));\n" + + "\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" + + "\t\trowPanel.add(createLabel(\"Fax\"));\n" + + "\t\trowPanel.add(createTextField(\"growx\"), \"growx\");\n" + + "\n" + + "\t\ttabbedPane.addTab(\"Column Span/Split\", colPanel);\n" + + "\t\ttabbedPane.addTab(\"Row Span\", rowPanel);"); + + return tabbedPane; + } + + public JComponent createGrowing() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // All tab + MigLayout allLM = new MigLayout("", + "[pref!][grow,fill]", + "[]15[]"); + JPanel allTab = createTabPanel(allLM); + allTab.add(createLabel("Fixed")); + allTab.add(createLabel("Gets all extra space"), "wrap"); + allTab.add(createTextField(5)); + allTab.add(createTextField(5)); + + // Half tab + MigLayout halfLM = new MigLayout("", + "[pref!][grow,fill]", + "[]15[]"); + JPanel halfTab = createTabPanel(halfLM); + halfTab.add(createLabel("Fixed")); + halfTab.add(createLabel("Gets half of extra space")); + halfTab.add(createLabel("Gets half of extra space"), "wrap"); + halfTab.add(createTextField(5)); + halfTab.add(createTextField(5)); + halfTab.add(createTextField(5)); + + // Percent 1 tab + MigLayout p1LM = new MigLayout("", + "[pref!][0:0,grow 25,fill][0:0,grow 75,fill]", + "[]15[]"); + JPanel p1Tab = createTabPanel(p1LM); + p1Tab.add(createLabel("Fixed")); + p1Tab.add(createLabel("Gets 25% of extra space"), ""); + p1Tab.add(createLabel("Gets 75% of extra space"), "wrap"); + p1Tab.add(createTextField(5)); + p1Tab.add(createTextField(5)); + p1Tab.add(createTextField(5)); + + // Percent 2 tab + MigLayout p2LM = new MigLayout("", + "[0:0,grow 33,fill][0:0,grow 67,fill]", + "[]15[]"); + JPanel p2Tab = createTabPanel(p2LM); + p2Tab.add(createLabel("Gets 33% of extra space"), ""); + p2Tab.add(createLabel("Gets 67% of extra space"), "wrap"); + p2Tab.add(createTextField(5)); + p2Tab.add(createTextField(5)); + + // Vertical 1 tab + MigLayout v1LM = new MigLayout("flowy", + "[]15[]", + "[][c,pref!][c,grow 25,fill][c,grow 75,fill]"); + JPanel v1Tab = createTabPanel(v1LM); + v1Tab.add(createLabel("Fixed"), "skip"); + v1Tab.add(createLabel("Gets 25% of extra space")); + v1Tab.add(createLabel("Gets 75% of extra space"), "wrap"); + v1Tab.add(createLabel("new JTextArea(4, 30)")); + v1Tab.add(createTextAreaScroll("", 4, 30, false)); + v1Tab.add(createTextAreaScroll("", 4, 30, false)); + v1Tab.add(createTextAreaScroll("", 4, 30, false)); + + // Vertical 2 tab + MigLayout v2LM = new MigLayout("flowy", + "[]15[]", + "[][c,grow 33,fill][c,grow 67,fill]"); + JPanel v2Tab = createTabPanel(v2LM); + v2Tab.add(createLabel("Gets 33% of extra space"), "skip"); + v2Tab.add(createLabel("Gets 67% of extra space"), "wrap"); + v2Tab.add(createLabel("new JTextArea(4, 30)")); + v2Tab.add(createTextAreaScroll("", 4, 30, false)); + v2Tab.add(createTextAreaScroll("", 4, 30, false)); + + tabbedPane.addTab("All", allTab); + tabbedPane.addTab("Half", halfTab); + tabbedPane.addTab("Percent 1", p1Tab); + tabbedPane.addTab("Percent 2", p2Tab); + tabbedPane.addTab("Vertical 1", v1Tab); + tabbedPane.addTab("Vertical 2", v2Tab); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// All tab\n" + + "MigLayout allLM = new MigLayout(\"\",\n" + + " \"[pref!][grow,fill]\",\n" + + " \"[]15[]\");\n" + + "JPanel allTab = createTabPanel(allLM);\n" + + "allTab.add(createLabel(\"Fixed\"));\n" + + "allTab.add(createLabel(\"Gets all extra space\"), \"wrap\");\n" + + "allTab.add(createTextField(5));\n" + + "allTab.add(createTextField(5));\n" + + "\n" + + "// Half tab\n" + + "MigLayout halfLM = new MigLayout(\"\",\n" + + " \"[pref!][grow,fill]\",\n" + + " \"[]15[]\");\n" + + "JPanel halfTab = createTabPanel(halfLM);\n" + + "halfTab.add(createLabel(\"Fixed\"));\n" + + "halfTab.add(createLabel(\"Gets half of extra space\"));\n" + + "halfTab.add(createLabel(\"Gets half of extra space\"), \"wrap\");\n" + + "halfTab.add(createTextField(5));\n" + + "halfTab.add(createTextField(5));\n" + + "halfTab.add(createTextField(5));\n" + + "\n" + + "// Percent 1 tab\n" + + "MigLayout p1LM = new MigLayout(\"\",\n" + + " \"[pref!][0:0,grow 25,fill][0:0,grow 75,fill]\",\n" + + " \"[]15[]\");\n" + + "JPanel p1Tab = createTabPanel(p1LM);\n" + + "p1Tab.add(createLabel(\"Fixed\"));\n" + + "p1Tab.add(createLabel(\"Gets 25% of extra space\"), \"\");\n" + + "p1Tab.add(createLabel(\"Gets 75% of extra space\"), \"wrap\");\n" + + "p1Tab.add(createTextField(5));\n" + + "p1Tab.add(createTextField(5));\n" + + "p1Tab.add(createTextField(5));\n" + + "\n" + + "// Percent 2 tab\n" + + "MigLayout p2LM = new MigLayout(\"\",\n" + + " \"[0:0,grow 33,fill][0:0,grow 67,fill]\",\n" + + " \"[]15[]\");\n" + + "JPanel p2Tab = createTabPanel(p2LM);\n" + + "p2Tab.add(createLabel(\"Gets 33% of extra space\"), \"\");\n" + + "p2Tab.add(createLabel(\"Gets 67% of extra space\"), \"wrap\");\n" + + "p2Tab.add(createTextField(5));\n" + + "p2Tab.add(createTextField(5));\n" + + "\n" + + "// Vertical 1 tab\n" + + "MigLayout v1LM = new MigLayout(\"flowy\",\n" + + " \"[]15[]\",\n" + + " \"[][c,pref!][c,grow 25,fill][c,grow 75,fill]\");\n" + + "JPanel v1Tab = createTabPanel(v1LM);\n" + + "v1Tab.add(createLabel(\"Fixed\"), \"skip\");\n" + + "v1Tab.add(createLabel(\"Gets 25% of extra space\"));\n" + + "v1Tab.add(createLabel(\"Gets 75% of extra space\"), \"wrap\");\n" + + "v1Tab.add(createLabel(\"new JTextArea(4, 30)\"));\n" + + "v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" + + "v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" + + "v1Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" + + "\n" + + "// Vertical 2 tab\n" + + "MigLayout v2LM = new MigLayout(\"flowy\",\n" + + " \"[]15[]\",\n" + + " \"[][c,grow 33,fill][c,grow 67,fill]\");\n" + + "JPanel v2Tab = createTabPanel(v2LM);\n" + + "v2Tab.add(createLabel(\"Gets 33% of extra space\"), \"skip\");\n" + + "v2Tab.add(createLabel(\"Gets 67% of extra space\"), \"wrap\");\n" + + "v2Tab.add(createLabel(\"new JTextArea(4, 30)\"));\n" + + "v2Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" + + "v2Tab.add(createTextAreaScroll(\"\", 4, 30, false));\n" + + "\n" + + "tabbedPane.addTab(\"All\", allTab);\n" + + "tabbedPane.addTab(\"Half\", halfTab);\n" + + "tabbedPane.addTab(\"Percent 1\", p1Tab);\n" + + "tabbedPane.addTab(\"Percent 2\", p2Tab);\n" + + "tabbedPane.addTab(\"Vertical 1\", v1Tab);\n" + + "tabbedPane.addTab(\"Vertical 2\", v2Tab);"); + + return tabbedPane; + } + + public JComponent createBasic_Sizes() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // Horizontal tab + MigLayout horLM = new MigLayout("", + "[]15[75px]25[min]25[]", + "[]15"); + JPanel horTab = createTabPanel(horLM); + horTab.add(createLabel("75px"), "skip"); + horTab.add(createLabel("Min")); + horTab.add(createLabel("Pref"), "wrap"); + + horTab.add(createLabel("new TextField(15)")); + horTab.add(createTextField(15)); + horTab.add(createTextField(15)); + horTab.add(createTextField(15)); + + // Vertical tab 1 + MigLayout verLM = new MigLayout("flowy,wrap", + "[]15[]", + "[]15[c,45px]15[c,min]15[c,pref]"); + JPanel verTab = createTabPanel(verLM); + verTab.add(createLabel("45px"), "skip"); + verTab.add(createLabel("Min")); + verTab.add(createLabel("Pref")); + + verTab.add(createLabel("new JTextArea(10, 40)")); + verTab.add(createTextArea("", 10, 40)); + verTab.add(createTextArea("", 10, 40)); + verTab.add(createTextArea("", 10, 40)); + + // Componentsized/Baseline 2 + MigLayout verLM2 = new MigLayout("flowy,wrap", + "[]15[]", + "[]15[baseline]15[baseline]15[baseline]"); + JPanel verTab2 = createTabPanel(verLM2); + verTab2.add(createLabel("45px"), "skip"); + verTab2.add(createLabel("Min")); + verTab2.add(createLabel("Pref")); + + verTab2.add(createLabel("new JTextArea(10, 40)")); + verTab2.add(createTextArea("", 10, 40), "height 45"); + verTab2.add(createTextArea("", 10, 40), "height min"); + verTab2.add(createTextArea("", 10, 40), "height pref"); + + tabbedPane.addTab("Horizontal - Column size set", horTab); + tabbedPane.addTab("Vertical - Row sized", verTab); + tabbedPane.addTab("Vertical - Component sized + Baseline", verTab2); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// Horizontal tab\n" + + "MigLayout horLM = new MigLayout(\"\",\n" + + " \"[]15[75px]25[min]25[]\",\n" + + " \"[]15\");\n" + + "JPanel horTab = createTabPanel(horLM);\n" + + "horTab.add(createLabel(\"75px\"), \"skip\");\n" + + "horTab.add(createLabel(\"Min\"));\n" + + "horTab.add(createLabel(\"Pref\"), \"wrap\");\n" + + "\n" + + "horTab.add(createLabel(\"new TextField(15)\"));\n" + + "horTab.add(createTextField(15));\n" + + "horTab.add(createTextField(15));\n" + + "horTab.add(createTextField(15));\n" + + "\n" + + "// Vertical tab 1\n" + + "MigLayout verLM = new MigLayout(\"flowy,wrap\",\n" + + " \"[]15[]\",\n" + + " \"[]15[c,45px]15[c,min]15[c,pref]\");\n" + + "JPanel verTab = createTabPanel(verLM);\n" + + "verTab.add(createLabel(\"45px\"), \"skip\");\n" + + "verTab.add(createLabel(\"Min\"));\n" + + "verTab.add(createLabel(\"Pref\"));\n" + + "\n" + + "verTab.add(createLabel(\"new JTextArea(10, 40)\"));\n" + + "verTab.add(createTextArea(\"\", 10, 40));\n" + + "verTab.add(createTextArea(\"\", 10, 40));\n" + + "verTab.add(createTextArea(\"\", 10, 40));\n" + + "\n" + + "// Componentsized/Baseline 2\n" + + "MigLayout verLM2 = new MigLayout(\"flowy,wrap\",\n" + + " \"[]15[]\",\n" + + " \"[]15[baseline]15[baseline]15[baseline]\");\n" + + "JPanel verTab2 = createTabPanel(verLM2);\n" + + "verTab2.add(createLabel(\"45px\"), \"skip\");\n" + + "verTab2.add(createLabel(\"Min\"));\n" + + "verTab2.add(createLabel(\"Pref\"));\n" + + "\n" + + "verTab2.add(createLabel(\"new JTextArea(10, 40)\"));\n" + + "verTab2.add(createTextArea(\"\", 10, 40), \"height 45\");\n" + + "verTab2.add(createTextArea(\"\", 10, 40), \"height min\");\n" + + "verTab2.add(createTextArea(\"\", 10, 40), \"height pref\");\n" + + "\n" + + "tabbedPane.addTab(\"Horizontal - Column size set\", horTab);\n" + + "tabbedPane.addTab(\"Vertical - Row sized\", verTab);\n" + + "tabbedPane.addTab(\"Vertical - Component sized + Baseline\", verTab2);"); + + return tabbedPane; + } + + public JComponent createAlignments() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // Horizontal tab + MigLayout horLM = new MigLayout("wrap", + "[label]15[left]15[center]15[right]15[fill]15[]", + "[]15[]"); + + String[] horLabels = new String[] {"[label]", "[left]", "[center]", "[right]", "[fill]", "[] (Default)"}; + JPanel horTab = createTabPanel(horLM); + String[] horNames = new String[] {"First Name", "Phone Number", "Facsmile", "Email", "Address", "Other"}; + for (int c = 0; c < horLabels.length; c++) + horTab.add(createLabel(horLabels[c])); + + for (int r = 0; r < horLabels.length; r++) { + for (int c = 0; c < horNames.length; c++) + horTab.add(c == 0 ? createLabel(horNames[r] + ":") : createButton(horNames[r])); + } + + // Vertical tab + MigLayout verLM = new MigLayout("wrap,flowy", + "[]unrel[]rel[]", + "[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]"); + + String[] verLabels = new String[] {"[top]", "[center]", "[bottom]", "[fill]", "[fill,baseline]", "[baseline]", "[] (Default)"}; + JPanel verTab = createTabPanel(verLM); + + String[] verNames = benchRuns == 0 ? new String[] {"<html>One</html>", "<html>One<br>Two</html>"} : new String[] {"One", "One/Two"}; + for (int c = 0; c < verLabels.length; c++) + verTab.add(createLabel(verLabels[c])); + + for (int r = 0; r < verNames.length; r++) { + for (int c = 0; c < verLabels.length; c++) + verTab.add(createButton(verNames[r])); + } + + for (int c = 0; c < verLabels.length; c++) + verTab.add(createTextField("JTextFied")); + + for (int c = 0; c < verLabels.length; c++) + verTab.add(createTextArea("JTextArea", 1, 8)); + + for (int c = 0; c < verLabels.length; c++) + verTab.add(createTextArea("JTextArea\nwith two lines", 1, 10)); + + for (int c = 0; c < verLabels.length; c++) + verTab.add(createTextAreaScroll("Scrolling JTextArea\nwith two lines", 1, 15, true)); + + tabbedPane.addTab("Horizontal", horTab); + tabbedPane.addTab("Vertical", verTab); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// Horizontal tab\n" + + "MigLayout horLM = new MigLayout(\"wrap\",\n" + + " \"[left]15[center]15[right]15[fill]15[]\",\n" + + " \"rel[]rel\");\n" + + "\n" + + "String[] horLabels = new String[] {\"[left]\", \"[center]\", \"[right]\", \"[fill]\", \"[] (Default)\"};\n" + + "JPanel horTab = createTabPanel(horLM);\n" + + "String[] horNames = new String[] {\"First Name\", \"Phone Number\", \"Facsmile\", \"Email\", \"Address\"};\n" + + "for (int c = 0; c < horLabels.length; c++)\n" + + "\thorTab.add(createLabel(horLabels[c]));\n" + + "\n" + + "for (int r = 0; r < horLabels.length; r++) {\n" + + "\tfor (int c = 0; c < horNames.length; c++)\n" + + "\t\thorTab.add(createButton(horNames[r]));\n" + + "}\n" + + "\n" + + "// Vertical tab\n" + + "MigLayout verLM = new MigLayout(\"wrap,flowy\",\n" + + " \"[]unrel[]rel[]\",\n" + + " \"[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]\");\n" + + "\n" + + "String[] verLabels = new String[] {\"[top]\", \"[center]\", \"[bottom]\", \"[fill]\", \"[fill,baseline]\", \"[baseline]\", \"[] (Default)\"};\n" + + "JPanel verTab = createTabPanel(verLM);\n" + + "\n" + + "String[] verNames = new String[] {\"<html>One</html>\", \"<html>One<br>Two</html>\"};\n" + + "for (int c = 0; c < verLabels.length; c++)\n" + + "\tverTab.add(createLabel(verLabels[c]));\n" + + "\n" + + "for (int r = 0; r < verNames.length; r++) {\n" + + "\tfor (int c = 0; c < verLabels.length; c++)\n" + + "\t\tverTab.add(createButton(verNames[r]));\n" + + "}\n" + + "\n" + + "for (int c = 0; c < verLabels.length; c++)\n" + + "\tverTab.add(createTextField(\"JTextFied\"));\n" + + "\n" + + "for (int c = 0; c < verLabels.length; c++)\n" + + "\tverTab.add(createTextArea(\"JTextArea\", 1, 8));\n" + + "\n" + + "for (int c = 0; c < verLabels.length; c++)\n" + + "\tverTab.add(createTextArea(\"JTextArea\\nwith two lines\", 1, 10));\n" + + "\n" + + "for (int c = 0; c < verLabels.length; c++)\n" + + "\tverTab.add(createTextAreaScroll(\"Scrolling JTextArea\\nwith two lines\", 1, 15, true));\n" + + "\n" + + "tabbedPane.addTab(\"Horizontal\", horTab);\n" + + "tabbedPane.addTab(\"Vertical\", verTab);"); + + return tabbedPane; + } + + public JComponent createQuick_Start() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + JPanel p = createTabPanel(new MigLayout("inset 20")); + + addSeparator(p, "General"); + + p.add(createLabel("Company"), "gap para"); + p.add(createTextField(""), "span, growx"); + p.add(createLabel("Contact"), "gap para"); + p.add(createTextField(""), "span, growx, wrap para"); + + addSeparator(p, "Propeller"); + + p.add(createLabel("PTI/kW"), "gap para"); + p.add(createTextField(10)); + p.add(createLabel("Power/kW"),"gap para"); + p.add(createTextField(10), "wrap"); + p.add(createLabel("R/mm"), "gap para"); + p.add(createTextField(10)); + p.add(createLabel("D/mm"), "gap para"); + p.add(createTextField(10)); + + tabbedPane.addTab("Quick Start", p); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "JPanel p = createTabPanel(new MigLayout());\n" + + "\n" + + "addSeparator(p, \"General\");\n" + + "\n" + + "p.add(createLabel(\"Company\"), \"gap para\");\n" + + "p.add(createTextField(\"\"), \"span, growx, wrap\");\n" + + "p.add(createLabel(\"Contact\"), \"gap para\");\n" + + "p.add(createTextField(\"\"), \"span, growx, wrap para\");\n" + + "\n" + + "addSeparator(p, \"Propeller\");\n" + + "\n" + + "p.add(createLabel(\"PTI/kW\"), \"gap para\");\n" + + "p.add(createTextField(10));\n" + + "p.add(createLabel(\"Power/kW\"),\"gap para\");\n" + + "p.add(createTextField(10), \"wrap\");\n" + + "p.add(createLabel(\"R/mm\"), \"gap para\");\n" + + "p.add(createTextField(10));\n" + + "p.add(createLabel(\"D/mm\"), \"gap para\");\n" + + "p.add(createTextField(10));\n" + + "\n" + + "tabbedPane.addTab(\"Quick Start\", p);"); + + return tabbedPane; + } + + public JComponent createGrow_Shrink() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + // shrink tab + MigLayout slm = new MigLayout("nogrid"); + JPanel sPanel = createTabPanel(slm); + + JScrollPane sDescrText = createTextAreaScroll("Use the slider to see how the components shrink depending on the constraints set on them.\n\n'shp' means Shrink Priority. " + + "Lower values will be shrunk before higer ones and the default value is 100.\n\n'shrink' means Shrink Weight. " + + "Lower values relative to other's means they will shrink less when space is scarse. " + + "Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\n\n" + + "The component's minimum size will always be honored.", 0, 0, true); + + sDescrText.setOpaque(OPAQUE); + sDescrText.setBorder(new EmptyBorder(10, 10, 10, 10)); + ((JTextArea) sDescrText.getViewport().getView()).setOpaque(OPAQUE); + sDescrText.getViewport().setOpaque(OPAQUE); + + JSplitPane sSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sPanel, sDescrText); + sSplitPane.setOpaque(OPAQUE); + sSplitPane.setBorder(null); + + sPanel.add(createTextField("shp 110", 12), "shp 110"); + sPanel.add(createTextField("Default (100)", 12), ""); + sPanel.add(createTextField("shp 90", 12), "shp 90"); + + sPanel.add(createTextField("shrink 25", 20), "newline,shrink 25"); + sPanel.add(createTextField("shrink 75", 20), "shrink 75"); + + sPanel.add(createTextField("Default", 20), "newline"); + sPanel.add(createTextField("Default", 20), ""); + + sPanel.add(createTextField("shrink 0", 40), "newline,shrink 0"); + + sPanel.add(createTextField("shp 110", 12), "newline,shp 110"); + sPanel.add(createTextField("shp 100,shrink 25", 12), "shp 100,shrink 25"); + sPanel.add(createTextField("shp 100,shrink 75", 12), "shp 100,shrink 75"); + tabbedPane.addTab("Shrink", sSplitPane); + + // Grow tab + MigLayout glm = new MigLayout("nogrid", "[grow]", ""); + JPanel gPanel = createTabPanel(glm); + + JScrollPane gDescrText = createTextAreaScroll("'gp' means Grow Priority. " + + "Higher values will be grown before lower ones and the default value is 100.\n\n'grow' means Grow Weight. " + + "Higher values relative to other's means they will grow more when space is up for takes. " + + "Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means " + + "components will normally not grow. \n\nNote that the buttons in the first and last row have max width set to 170 to " + + "emphasize Grow Priority.\n\nThe component's maximum size will always be honored.", 0, 0, true); + + gDescrText.setOpaque(OPAQUE); + gDescrText.setBorder(new EmptyBorder(10, 10, 10, 10)); + ((JTextArea) gDescrText.getViewport().getView()).setOpaque(OPAQUE); + gDescrText.getViewport().setOpaque(OPAQUE); + + JSplitPane gSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, gPanel, gDescrText); + gSplitPane.setOpaque(OPAQUE); + gSplitPane.setBorder(null); + + gPanel.add(createButton("gp 110,grow"), "gp 110,grow,wmax 170"); + gPanel.add(createButton("Default (100),grow"), "grow,wmax 170"); + gPanel.add(createButton("gp 90,grow"), "gp 90,grow,wmax 170"); + + gPanel.add(createButton("Default Button"), "newline"); + + gPanel.add(createButton("growx"), "newline,growx,wrap"); + + gPanel.add(createButton("gp 110,grow"), "gp 110,grow,wmax 170"); + gPanel.add(createButton("gp 100,grow 25"), "gp 100,grow 25,wmax 170"); + gPanel.add(createButton("gp 100,grow 75"), "gp 100,grow 75,wmax 170"); + tabbedPane.addTab("Grow", gSplitPane); + + // Disregard. Just forgetting the source code text close to the source code. + setSource("JTabbedPane tabbedPane = new JTabbedPane();\n" + + "\n" + + "// shrink tab\n" + + "MigLayout slm = new MigLayout(\"nogrid\");\n" + + "JPanel sPanel = createTabPanel(slm);\n" + + "\n" + + "JScrollPane sDescrText = createTextAreaScroll(\"Use the slider to see how the components shrink depending on the constraints set on them.\\n\\n'shp' means Shrink Priority. \" +\n" + + " \"Lower values will be shrunk before higer ones and the default value is 100.\\n\\n'shrink' means Shrink Weight. \" +\n" + + " \"Lower values relative to other's means they will shrink less when space is scarse. \" +\n" + + " \"Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\\n\\n\" +\n" + + " \"The component's minimum size will always be honored.\", 0, 0, true);\n" + + "\n" + + "sDescrText.setOpaque(OPAQUE);\n" + + "sDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" + + "((JTextArea) sDescrText.getViewport().getView()).setOpaque(OPAQUE);\n" + + "sDescrText.getViewport().setOpaque(OPAQUE);\n" + + "\n" + + "JSplitPane sSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sPanel, sDescrText);\n" + + "sSplitPane.setOpaque(OPAQUE);\n" + + "sSplitPane.setBorder(null);\n" + + "\n" + + "sPanel.add(createTextField(\"shp 110\", 12), \"shp 110\");\n" + + "sPanel.add(createTextField(\"Default (100)\", 12), \"\");\n" + + "sPanel.add(createTextField(\"shp 90\", 12), \"shp 90\");\n" + + "\n" + + "sPanel.add(createTextField(\"shrink 25\", 20), \"newline,shrink 25\");\n" + + "sPanel.add(createTextField(\"shrink 75\", 20), \"shrink 75\");\n" + + "\n" + + "sPanel.add(createTextField(\"Default\", 20), \"newline\");\n" + + "sPanel.add(createTextField(\"Default\", 20), \"\");\n" + + "\n" + + "sPanel.add(createTextField(\"shrink 0\", 40), \"newline,shrink 0\");\n" + + "\n" + + "sPanel.add(createTextField(\"shp 110\", 12), \"newline,shp 110\");\n" + + "sPanel.add(createTextField(\"shp 100,shrink 25\", 12), \"shp 100,shrink 25\");\n" + + "sPanel.add(createTextField(\"shp 100,shrink 75\", 12), \"shp 100,shrink 75\");\n" + + "tabbedPane.addTab(\"Shrink\", sSplitPane);\n" + + "\n" + + "// Grow tab\n" + + "MigLayout glm = new MigLayout(\"nogrid\", \"[grow]\", \"\");\n" + + "JPanel gPanel = createTabPanel(glm);\n" + + "\n" + + "JScrollPane gDescrText = createTextAreaScroll(\"'gp' means Grow Priority. \" +\n" + + " \"Higher values will be grown before lower ones and the default value is 100.\\n\\n'grow' means Grow Weight. \" +\n" + + " \"Higher values relative to other's means they will grow more when space is up for takes. \" +\n" + + " \"Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means \" +\n" + + " \"components will normally not grow. \\n\\nNote that the buttons in the first and last row have max width set to 170 to \" +\n" + + " \"emphasize Grow Priority.\\n\\nThe component's maximum size will always be honored.\", 0, 0, true);\n" + + "\n" + + "gDescrText.setOpaque(OPAQUE);\n" + + "gDescrText.setBorder(new EmptyBorder(10, 10, 10, 10));\n" + + "((JTextArea) gDescrText.getViewport().getView()).setOpaque(OPAQUE);\n" + + "gDescrText.getViewport().setOpaque(OPAQUE);\n" + + "\n" + + "JSplitPane gSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, gPanel, gDescrText);\n" + + "gSplitPane.setOpaque(OPAQUE);\n" + + "gSplitPane.setBorder(null);\n" + + "\n" + + "gPanel.add(createButton(\"gp 110,grow\"), \"gp 110,grow,wmax 170\");\n" + + "gPanel.add(createButton(\"Default (100),grow\"), \"grow,wmax 170\");\n" + + "gPanel.add(createButton(\"gp 90,grow\"), \"gp 90,grow,wmax 170\");\n" + + "\n" + + "gPanel.add(createButton(\"Default Button\"), \"newline\");\n" + + "\n" + + "gPanel.add(createButton(\"growx\"), \"newline,growx,wrap\");\n" + + "\n" + + "gPanel.add(createButton(\"gp 110,grow\"), \"gp 110,grow,wmax 170\");\n" + + "gPanel.add(createButton(\"gp 100,grow 25\"), \"gp 100,grow 25,wmax 170\");\n" + + "gPanel.add(createButton(\"gp 100,grow 75\"), \"gp 100,grow 75,wmax 170\");\n" + + "tabbedPane.addTab(\"Grow\", gSplitPane);"); + + return tabbedPane; + } + + public JComponent createPlainApi() + { + JTabbedPane tabbedPane = new JTabbedPane(); + + MigLayout lm = new MigLayout(new LC(), null, null); + JPanel panel = createTabPanel(lm); + + addSeparator(panel, "Manufacturer"); + panel.add(createLabel("Company")); + panel.add(createTextField(""), "span,growx"); + panel.add(createLabel("Contact")); + panel.add(createTextField(""), "span,growx"); + panel.add(createLabel("Order No")); + panel.add(createTextField(15), "wrap"); + + addSeparator(panel, "Inspector"); + panel.add(createLabel("Name")); + panel.add(createTextField(""), "span,growx"); + panel.add(createLabel("Reference No")); + panel.add(createTextField(""), "wrap"); + panel.add(createLabel("Status")); + panel.add(createCombo(new String[] {"In Progress", "Finnished", "Released"}), "wrap"); + + addSeparator(panel, "Ship"); + panel.add(createLabel("Shipyard")); + panel.add(createTextField(""), "span,growx"); + panel.add(createLabel("Register No")); + panel.add(createTextField("")); + panel.add(createLabel("Hull No"), "right"); + panel.add(createTextField(15), "wrap"); + panel.add(createLabel("Project Type")); + panel.add(createCombo(new String[] {"New Building", "Convention", "Repair"})); + + tabbedPane.addTab("Plain", panel); + + return tabbedPane; + } + + // ********************************************************** + // * Helper Methods + // ********************************************************** + + private final ToolTipListener toolTipListener = new ToolTipListener(); + private final ConstraintListener constraintListener = new ConstraintListener(); + + private JLabel createLabel(String text) + { + return createLabel(text, SwingConstants.LEADING); + } + + private JLabel createLabel(String text, int align) + { + final JLabel b = new JLabel(text, align); + configureActiveComponet(b); + return b; + } + + public JComboBox createCombo(String[] items) + { + JComboBox combo = new JComboBox(items); + + if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.MAC_OSX) + combo.setOpaque(false); + + return combo; + } + + private JTextField createTextField(int cols) + { + return createTextField("", cols); + } + + private JTextField createTextField(String text) + { + return createTextField(text, 0); + } + + private JTextField createTextField(String text, int cols) + { + final JTextField b = new JTextField(text, cols); + + configureActiveComponet(b); + + return b; + } + + private static final Font BUTT_FONT = new Font("monospaced", Font.PLAIN, 12); + private JButton createButton() + { + return createButton(""); + } + + private JButton createButton(String text) + { + return createButton(text, false); + } + + private JButton createButton(String text, boolean bold) + { + JButton b = new JButton(text) { + public void addNotify() + { + super.addNotify(); + if (benchRuns == 0) { // Since this does not exist in the SWT version + if (getText().length() == 0) { + String lText = (String) ((MigLayout) getParent().getLayout()).getComponentConstraints(this); + setText(lText != null && lText.length() > 0 ? lText : "<Empty>"); + } + } else { + setText("Benchmark Version"); + } + } + }; + + if (bold) + b.setFont(b.getFont().deriveFont(Font.BOLD)); + + configureActiveComponet(b); + + b.setOpaque(buttonOpaque); // Or window's buttons will have strange border + + if (PlatformDefaults.getCurrentPlatform() == PlatformDefaults.MAC_OSX) + b.setContentAreaFilled(false); + + return b; + } + + private JToggleButton createToggleButton(String text) + { + JToggleButton b = new JToggleButton(text); +// configureActiveComponet(b); + b.setOpaque(buttonOpaque); // Or window's buttons will have strange border + return b; + } + + private JCheckBox createCheck(String text) + { + JCheckBox b = new JCheckBox(text); + + configureActiveComponet(b); + + b.setOpaque(OPAQUE); // Or window's checkboxes will have strange border + return b; + } + + private JPanel createTabPanel(LayoutManager lm) + { + JPanel panel = new JPanel(lm); + configureActiveComponet(panel); + panel.setOpaque(OPAQUE); + return panel; + } + + private JComponent createPanel() + { + return createPanel(""); + } + + private JComponent createPanel(String s) + { + JLabel panel = new JLabel(s, SwingConstants.CENTER) { + public void addNotify() + { + super.addNotify(); + if (benchRuns == 0) { // Since this does not exist in the SWT version + if (getText().length() == 0) { + String lText = (String) ((MigLayout) getParent().getLayout()).getComponentConstraints(this); + setText(lText != null && lText.length() > 0 ? lText : "<Empty>"); + } + } + } + }; + panel.setBorder(new EtchedBorder()); + panel.setOpaque(true); + configureActiveComponet(panel); + + return panel; + } + + private JTextArea createTextArea(String text, int rows, int cols) + { + JTextArea ta = new JTextArea(text, rows, cols); + ta.setBorder(UIManager.getBorder("TextField.border")); + ta.setFont(UIManager.getFont("TextField.font")); + ta.setWrapStyleWord(true); + ta.setLineWrap(true); + + configureActiveComponet(ta); + + return ta; + } + + private JScrollPane createTextAreaScroll(String text, int rows, int cols, boolean hasVerScroll) + { + JTextArea ta = new JTextArea(text, rows, cols); + ta.setFont(UIManager.getFont("TextField.font")); + ta.setWrapStyleWord(true); + ta.setLineWrap(true); + + JScrollPane scroll = new JScrollPane( + ta, + hasVerScroll ? ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED : ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + return scroll; + } + + private JComponent configureActiveComponet(JComponent c) + { + if (benchRuns == 0) { + c.addMouseMotionListener(toolTipListener); + c.addMouseListener(constraintListener); + } + return c; + } + + static final Color LABEL_COLOR = new Color(0, 70, 213); + private void addSeparator(JPanel panel, String text) + { + JLabel l = createLabel(text); + l.setForeground(LABEL_COLOR); + + panel.add(l, "gapbottom 1, span, split 2"); + panel.add(configureActiveComponet(new JSeparator()), "gapleft rel, growx"); + } + + private class ConstraintListener extends MouseAdapter + { + public void mousePressed(MouseEvent e) + { + if (e.isPopupTrigger()) + react(e); + } + + public void mouseReleased(MouseEvent e) + { + if (e.isPopupTrigger()) + react(e); + } + + public void react(MouseEvent e) + { + JComponent c = (JComponent) e.getSource(); + LayoutManager lm = c.getParent().getLayout(); + if (lm instanceof MigLayout == false) + lm = c.getLayout(); + + if (lm instanceof MigLayout) { + MigLayout layout = (MigLayout) lm; + boolean isComp = layout.isManagingComponent(c); + + Object compConstr = isComp ? layout.getComponentConstraints(c) : null; + if (isComp && compConstr == null) + compConstr = ""; + + Object rowsConstr = isComp ? null : layout.getRowConstraints(); + Object colsConstr = isComp ? null : layout.getColumnConstraints(); + Object layoutConstr = isComp ? null : layout.getLayoutConstraints(); + + ConstraintsDialog cDlg = new ConstraintsDialog(SwingDemo.this, + layoutConstr instanceof LC ? IDEUtil.getConstraintString((LC) layoutConstr, false) : (String) layoutConstr, + rowsConstr instanceof AC ? IDEUtil.getConstraintString((AC) rowsConstr, false, false) : (String) rowsConstr, + colsConstr instanceof AC ? IDEUtil.getConstraintString((AC) colsConstr, false, false) : (String) colsConstr, + compConstr instanceof CC ? IDEUtil.getConstraintString((CC) colsConstr, false) : (String) compConstr); + + cDlg.pack(); + cDlg.setLocationRelativeTo(c); + + if (cDlg.showDialog()) { + try { + if (isComp) { + String constrStr = cDlg.componentConstrTF.getText().trim(); + layout.setComponentConstraints(c, constrStr); + if (c instanceof JButton) { + c.setFont(BUTT_FONT); + ((JButton) c).setText(constrStr.length() == 0 ? "<Empty>" : constrStr); + } + } else { + layout.setLayoutConstraints(cDlg.layoutConstrTF.getText()); + layout.setRowConstraints(cDlg.rowsConstrTF.getText()); + layout.setColumnConstraints(cDlg.colsConstrTF.getText()); + } + } catch(Exception ex) { + StringWriter sw = new StringWriter(); + ex.printStackTrace(new PrintWriter(sw)); + JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(c), sw.toString(), "Error parsing Constraint!", JOptionPane.ERROR_MESSAGE); + return; + } + + c.invalidate(); + c.getParent().validate(); + } + } + } + } + + private static class ToolTipListener extends MouseMotionAdapter + { + public void mouseMoved(MouseEvent e) + { + JComponent c = (JComponent) e.getSource(); + LayoutManager lm = c.getParent().getLayout(); + if (lm instanceof MigLayout) { + String constr = (String) ((MigLayout) lm).getComponentConstraints(c); + c.setToolTipText((constr != null ? ("\"" + constr + "\"") : "null")); + } + } + } + + private static class ConstraintsDialog extends JDialog implements ActionListener, KeyEventDispatcher + { + private static final Color ERROR_COLOR = new Color(255, 180, 180); + private final JPanel mainPanel = new JPanel(new MigLayout("fillx,flowy,ins dialog", + "[fill]", + "2[]2")); + final JTextField layoutConstrTF; + final JTextField rowsConstrTF; + final JTextField colsConstrTF; + final JTextField componentConstrTF; + + private final JButton okButt = new JButton("OK"); + private final JButton cancelButt = new JButton("Cancel"); + + private boolean okPressed = false; + + public ConstraintsDialog(Frame owner, String layoutConstr, String rowsConstr, String colsConstr, String compConstr) + { + super(owner, (compConstr != null ? "Edit Component Constraints" : "Edit Container Constraints"), true); + + layoutConstrTF = createConstraintField(layoutConstr); + rowsConstrTF = createConstraintField(rowsConstr); + colsConstrTF = createConstraintField(colsConstr); + componentConstrTF = createConstraintField(compConstr); + + if (componentConstrTF != null) { + mainPanel.add(new JLabel("Component Constraints")); + mainPanel.add(componentConstrTF); + } + + if (layoutConstrTF != null) { + mainPanel.add(new JLabel("Layout Constraints")); + mainPanel.add(layoutConstrTF); + } + + if (colsConstrTF != null) { + mainPanel.add(new JLabel("Column Constraints"), "gaptop unrel"); + mainPanel.add(colsConstrTF); + } + + if (rowsConstrTF != null) { + mainPanel.add(new JLabel("Row Constraints"), "gaptop unrel"); + mainPanel.add(rowsConstrTF); + } + + mainPanel.add(okButt, "tag ok,split,flowx,gaptop 15"); + mainPanel.add(cancelButt, "tag cancel,gaptop 15"); + + setContentPane(mainPanel); + + okButt.addActionListener(this); + cancelButt.addActionListener(this); + } + + public void addNotify() + { + super.addNotify(); + KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); + } + + public void removeNotify() + { + KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this); + super.removeNotify(); + } + + public boolean dispatchKeyEvent(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) + dispose(); + return false; + } + + public void actionPerformed(ActionEvent e) + { + if (e.getSource() == okButt) + okPressed = true; + dispose(); + } + + private JTextField createConstraintField(String text) + { + if (text == null) + return null; + + final JTextField tf = new JTextField(text, 50); + tf.setFont(new Font("monospaced", Font.PLAIN, 12)); + + tf.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + okButt.doClick(); + return; + } + + javax.swing.Timer timer = new Timer(50, new ActionListener() { + public void actionPerformed(ActionEvent e) + { + String constr = tf.getText(); + try { + if (tf == layoutConstrTF) { + ConstraintParser.parseLayoutConstraint(constr); + } else if (tf == rowsConstrTF) { + ConstraintParser.parseRowConstraints(constr); + } else if (tf == colsConstrTF) { + ConstraintParser.parseColumnConstraints(constr); + } else if (tf == componentConstrTF) { + ConstraintParser.parseComponentConstraint(constr); + } + + tf.setBackground(Color.WHITE); + okButt.setEnabled(true); + } catch(Exception ex) { + tf.setBackground(ERROR_COLOR); + okButt.setEnabled(false); + } + } + }); + timer.setRepeats(false); + timer.start(); + } + }); + + return tf; + } + + private boolean showDialog() + { + setVisible(true); + return okPressed; + } + } + }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/demo/SwtDemo.java b/prototypes/miglayout/net/miginfocom/demo/SwtDemo.java index 43bcf538..76edda00 100644 --- a/prototypes/miglayout/net/miginfocom/demo/SwtDemo.java +++ b/prototypes/miglayout/net/miginfocom/demo/SwtDemo.java @@ -1,2100 +1,2100 @@ -package net.miginfocom.demo;
-
-import net.miginfocom.layout.*;
-import net.miginfocom.swt.MigLayout;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.*;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Random;
-
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-public class SwtDemo
-{
- public static final int SELECTED_INDEX = 0;
-
- private static final String[][] panels = new String[][] {
-// {"Test", "Test, Disregard"},
- {"Welcome", "\n\n \"MigLayout makes complex layouts easy and normal layouts one-liners.\""},
- {"Quick Start", "This is an example of how to build a common dialog type. Note that there are no special components, nested panels or absolute references to cell positions. If you look at the source code you will see that the layout code is very simple to understand."},
- {"Plain", "A simple example on how simple it is to create normal forms. No builders needed since the whole layout manager works like a builder."},
- {"Alignments", "Shows how the alignment of components are specified. At the top/left is the alignment for the column/row. The components have no alignments specified.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."},
- {"Cell Alignments", "Shows how components are aligned when both column/row alignments and component constraints are specified. At the top/left are the alignment for the column/row and the text on the buttons is the component constraint that will override the column/row alignment if it is an alignment.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."},
- {"Basic Sizes", "A simple example that shows how to use the column or row min/preferred/max size to set the sizes of the contained components and also an example that shows how to do this directly in the component constraints."},
- {"Growing", "A simple example that shows how to use the growx and growy constraint to set the sizes and how they should grow to fit the available size. Both the column/row and the component grow/shrink constraints can be set, but the components will always be confined to the space given by its column/row."},
- {"Grow Shrink", "Demonstrates the very flexible grow and shrink constraints that can be set on a component.\nComponents can be divided into grow/shrink groups and also have grow/shrink weight within each of those groups.\n\nBy default " +
- "components shrink to their inherent (or specified) minimum size, but they don't grow."},
- {"Span", "This example shows the powerful spanning and splitting that can be specified in the component constraints. With spanning any number of cells can be merged with the additional option to split that space for more than one component. This makes layouts very flexible and reduces the number of times you will need nested panels to very few."},
- {"Flow Direction", "Shows the different flow directions. Flow direction for the layout specifies if the next cell will be in the x or y dimension. Note that it can be a different flow direction in the slit cell (the middle cell is slit in two). Wrap is set to 3 for all panels."},
- {"Grouping", "Sizes for both components and columns/rows can be grouped so they get the same size. For instance buttons in a button bar can be given a size-group so that they will all get " +
- "the same minimum and preferred size (the largest within the group). Size-groups can be set for the width, height or both."},
- {"Units", "Demonstrates the basic units that are understood by MigLayout. These units can be extended by the user by adding one or more UnitConverter(s)."},
- {"Component Sizes", "Minimum, preferred and maximum component sizes can be overridden in the component constraints using any unit type. The format to do this is short and simple to understand. You simply specify the " +
- "min, preferred and max sizes with a colon between.\n\nAbove are some examples of this. An exclamation mark means that the value will be used for all sizes."},
- {"Bound Sizes", "Shows how to create columns that are stable between tabs using minimum sizes."},
- {"Cell Position", "Even though MigLayout has automatic grid flow you can still specify the cell position explicitly. You can even combine absolute (x, y) and flow (skip, wrap and newline) constraints to build your layout."},
- {"Orientation", "MigLayout supports not only right-to-left orientation, but also bottom-to-top. You can even set the flow direction so that the flow is vertical instead of horizontal. It will automatically " +
- "pick up if right-to-left is to be used depending on the ComponentWrapper, but it can also be manually set for every layout."},
- {"Absolute Position", "Demonstrates the option to place any number of components using absolute coordinates. This can be just the position (if min/preferred size) using \"x y p p\" format or" +
- "the bounds using the \"x1 y1 x2 y2\" format. Any unit can be used and percent is relative to the parent.\nAbsolute components will not disturb the flow or occupy cells in the grid. " +
- "Absolute positioned components will be taken into account when calculating the container's preferred size."},
- {"Component Links", "Components can be linked to any side of any other component. It can be a forward, backward or cyclic link references, as long as it is stable and won't continue to change value over many iterations." +
- "Links are referencing the ID of another component. The ID can be overridden by the component's constrains or is provided by the ComponentWrapper. For instance it will use the component's 'name' on Swing.\n" +
- "Since the links can be combined with any expression (such as 'butt1.x+10' or 'max(button.x, 200)' the links are very customizable."},
- {"Docking", "Docking components can be added around the grid. The docked component will get the whole width/height on the docked side by default, however this can be overridden. When all docked components are laid out, whatever space " +
- "is left will be available for the normal grid laid out components. Docked components does not in any way affect the flow in the grid.\n\nSince the docking runs in the same code path " +
- "as the normal layout code the same properties can be specified for the docking components. You can for instance set the sizes and alignment or link other components to their docked component's bounds."},
- {"Button Bars", "Button order is very customizable and are by default different on the supported platforms. E.g. Gaps, button order and minimum button size are properties that are 'per platform'. MigLayout picks up the current platform automatically and adjusts the button order and minimum button size accordingly, all without using a button builder or any other special code construct."},
- {"Debug", "Demonstrates the non-intrusive way to get visual debugging aid. There is no need to use a special DebugPanel or anything that will need code changes. The user can simply turn on debug on the layout manager by using the debug constraint and it will " +
- "continuously repaint the panel with debug information on top. This means you don't have to change your code to debug!"},
- {"Layout Showdown", "This is an implementation of the Layout Showdown posted on java.net by John O'Conner. The first tab is a pure implemenetation of the showdown that follows all the rules. The second tab is a slightly fixed version that follows some improved layout guidelines." +
- "The source code is for bothe the first and for the fixed version. Note the simplification of the code for the fixed version. Writing better layouts with MiG Layout is reasier that writing bad.\n\nReference: http://weblogs.java.net/blog/joconner/archive/2006/10/more_informatio.html"},
- {"API Constraints1", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."},
- {"API Constraints2", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."},
- };
-
- private static int DOUBLE_BUFFER = 0;//SWT.DOUBLE_BUFFERED;
-
- private static int benchRuns = 0;
- private static long startupMillis = 0;
- private static long timeToShowMillis = 0;
- private static long benchRunTime = 0;
- private static String benchOutFileName = null;
- private static boolean append = false;
-
- private static long lastRunTimeStart = 0;
- private static StringBuffer runTimeSB = null;
-
- private static Display display = null;
-
- public static void main(String[] args)
- {
- startupMillis = System.currentTimeMillis();
-
- if (args.length > 0) {
- for (int i = 0; i < args.length; i++) {
- String arg = args[i].trim();
- if (arg.startsWith("-bench")) {
- benchRuns = 10;
- try {
- if (arg.length() > 6)
- benchRuns = Integer.parseInt(arg.substring(6));
- } catch (Exception ex) {}
- } else if (arg.startsWith("-bout")) {
- benchOutFileName = arg.substring(5);
- } else if (arg.startsWith("-append")) {
- append = true;
- } else if (arg.startsWith("-verbose")) {
- runTimeSB = new StringBuffer(256);
- } else {
- System.out.println("Usage: [-bench[#_of_runs]] [-bout[benchmark_results_filename]] [-append]\n" +
- " -bench Run demo as benchmark. Run count can be appended. 10 is default.\n" +
- " -bout Benchmark results output filename.\n" +
- " -append Appends the result to the \"-bout\" file.\n" +
- " -verbose Print the times of every run.\n" +
- "\nExamples:\n" +
- " java -jar swtdemoapp.jar -bench -boutC:/bench.txt -append\n" +
- " java -jar swtdemoapp.jar -bench20\n" +
- "NOTE! swt-win32-3232.dll must be in the current directory!");
- System.exit(0);
- }
- }
- }
-
- if (benchRuns > 0)
- LayoutUtil.setDesignTime(null, true);
-
- new SwtDemo();
- }
-
- final List pickerList;
- final Composite layoutDisplayPanel;
- final StyledText descrTextArea;
-
- public SwtDemo()
- {
- display = new Display();
- final Shell shell = new Shell();
-
- shell.setLayout(new MigLayout("wrap", "[]u[grow,fill]", "[grow,fill][pref!]"));
- shell.setText("MigLayout SWT Demo v2.5 - Mig Layout v" + LayoutUtil.getVersion());
-
- TabFolder layoutPickerTabPane = new TabFolder(shell, DOUBLE_BUFFER);
- layoutPickerTabPane.setLayoutData("spany,grow");
- pickerList = new List(layoutPickerTabPane, SWT.SINGLE | DOUBLE_BUFFER);
- deriveFont(pickerList, SWT.BOLD, -1);
- TabItem tab = new TabItem(layoutPickerTabPane, DOUBLE_BUFFER);
- tab.setControl(pickerList);
- tab.setText("Example Browser");
- for (int i = 0; i < panels.length; i++)
- pickerList.add(panels[i][0]);
-
- layoutDisplayPanel = new Composite(shell, DOUBLE_BUFFER);
- layoutDisplayPanel.setLayout(new MigLayout("fill, insets 0"));
-
- TabFolder descriptionTabPane = new TabFolder(shell, DOUBLE_BUFFER);
- descriptionTabPane.setLayoutData("growx,hmin 120,w 500:500");
- descrTextArea = createTextArea(descriptionTabPane, "", "", SWT.MULTI | SWT.WRAP);
- tab = new TabItem(descriptionTabPane, DOUBLE_BUFFER);
- tab.setControl(descrTextArea);
- tab.setText("Description");
-
- pickerList.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent e) {
- dispatchSelection();
- }
- });
-
- shell.setSize(900, 650);
- shell.open();
-
- shell.layout();
-
-
- if (benchRuns > 0) {
- doBenchmark();
- } else {
- pickerList.select(SELECTED_INDEX);
- dispatchSelection();
-
- display.addFilter(SWT.KeyDown, new Listener() {
-
- public void handleEvent(Event e)
- {
- if (e.character == 'b') {
- startupMillis = System.currentTimeMillis();
- timeToShowMillis = System.currentTimeMillis() - startupMillis;
- benchRuns = 1;
- doBenchmark();
- }
- }
- });
- }
-
- while(!shell.isDisposed()){
- if(!display.readAndDispatch())
- display.sleep();
- }
-
- display.dispose();
- }
-
- private static Control[] comps = null; // thread hack...
- private static Control[] tabs = null; // thread hack...
-
- private void doBenchmark()
- {
- final int pCnt = pickerList.getItemCount();
- Thread benchThread = new Thread() {
- public void run()
- {
- for (int j = 0; j < benchRuns; j++) {
- lastRunTimeStart = System.currentTimeMillis();
- final int jj = j;
- for (int i = 0; i < pCnt; i++) {
- final int ii = i;
- try {
- display.syncExec(new Runnable() {
- public void run () {
- pickerList.setSelection(ii);
- dispatchSelection();
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- display.syncExec(new Runnable() {
- public void run() {
- comps = layoutDisplayPanel.getChildren();
- }
- });
-
- for (int cIx = 0; cIx < comps.length; cIx++) {
-
- if (comps[cIx] instanceof TabFolder) {
- final TabFolder tp = (TabFolder) comps[cIx];
-
- display.syncExec(new Runnable() {
- public void run() {
- tabs = tp.getTabList();
- }
- });
-
- for (int k = 0; k < tabs.length; k++) {
- final int kk = k;
- try {
- display.syncExec(new Runnable() {
- public void run() {
- tp.setSelection(kk);
-
- if (timeToShowMillis == 0)
- timeToShowMillis = System.currentTimeMillis() - startupMillis;
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
- };
- }
- }
- }
- }
- if (runTimeSB != null) {
- runTimeSB.append("Run ").append(jj).append(": ");
- runTimeSB.append(System.currentTimeMillis() - lastRunTimeStart).append(" millis.\n");
- }
- }
-
- benchRunTime = System.currentTimeMillis() - startupMillis - timeToShowMillis;
-
- final String message = "Java Version: " + System.getProperty("java.version") + "\n" +
- "Time to Show: " + timeToShowMillis + " millis.\n" +
- (runTimeSB != null ? runTimeSB.toString() : "") +
- "Benchmark Run Time: " + benchRunTime + " millis.\n" +
- "Average Run Time: " + (benchRunTime / benchRuns) + " millis (" + benchRuns + " runs).\n\n";
-
- display.syncExec(new Runnable() {
- public void run() {
- if (benchOutFileName == null) {
- MessageBox messageBox = new MessageBox(display.getActiveShell(), SWT.OK | SWT.ICON_INFORMATION);
- messageBox.setText("Results");
- messageBox.setMessage(message);
- messageBox.open();
- } else {
- FileWriter fw = null;
- try {
- fw = new FileWriter(benchOutFileName, append);
- fw.write(message);
- } catch(IOException ex) {
- ex.printStackTrace();
- } finally {
- if (fw != null)
- try {fw.close();} catch(IOException ex) {}
- }
- }
- }
- });
-
- System.out.println(message);
-
- if (benchOutFileName != null)
- System.exit(0);
- }
- };
- benchThread.start();
- }
-
- private void dispatchSelection()
- {
- int ix = pickerList.getSelectionIndex();
- if (ix == -1)
- return;
-
- String methodName = "create" + panels[ix][0].replace(' ', '_');
- Control[] children = layoutDisplayPanel.getChildren();
- for (int i = 0; i < children.length; i++)
- children[i].dispose();
-
- try {
- Control child = (Control) SwtDemo.class.getMethod(methodName, new Class[] {Composite.class}).invoke(SwtDemo.this, new Object[] {layoutDisplayPanel});
- child.setLayoutData("grow, wmin 500");
- descrTextArea.setText(panels[ix][1]);
- layoutDisplayPanel.layout();
- } catch (Exception e1) {
- e1.printStackTrace(); // Should never happpen...
- }
- }
-
- public Control createTest(Composite parent2)
- {
-// TabFolder tabFolder = new TabFolder(parent2, DOUBLE_BUFFER);
-
- Composite parent = new Composite(parent2, SWT.NONE);
-
- MigLayout layout = new MigLayout("wrap 2");
- layout.setColumnConstraints("[grow, shrink][grow, shrink]");
- parent.setLayout(layout);
-
- Label label = new Label(parent, SWT.WRAP);
- label.setText("This is a long label");
- label.setLayoutData("width 20:pref:pref");
-
- label = new Label(parent, SWT.NONE);
- label.setText("Label 2");
-
- label = new Label(parent, SWT.NONE);
- label.setText("Label 3");
-
- label = new Label(parent, SWT.NONE);
- label.setText("Label 4");
-
- return parent;
- }
-
- public Control createWelcome(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- TabItem mainItem = createTabPanel(tabbedPane, "Welcome", new FillLayout());
- MigLayout lm = new MigLayout("ins 30, fill");
- Composite panel = createPanel(tabbedPane, lm);
- mainItem.setControl(panel);
-
- String s = "MigLayout's main purpose is to make layouts for SWT and Swing, and possibly other frameworks, much more powerful and a lot easier to create, especially for manual coding.\n\n" +
- "The motto is: \"MigLayout makes complex layouts easy and normal layouts one-liners.\"\n\n" +
- "The layout engine is very flexible and advanced, something that is needed to make it simple to use yet handle almost all layout use-cases.\n\n" +
- "MigLayout can handle all layouts that the commonly used Swing Layout Managers can handle and this with a lot of extra features. " +
- "It also incorporates most, if not all, of the open source alternatives FormLayout's and TableLayout's functionality." +
- "\n\n\nThanks to Karsten Lentzsch of JGoodies.com for allowing the reuse of the main demo application layout and for his inspiring talks that led to this layout Manager." +
- "\n\n\nMikael Grev\n" +
- "MiG InfoCom AB\n" +
- "miglayout@miginfocom.com";
-
- StyledText textArea = new StyledText(panel, SWT.MULTI | SWT.WRAP | SWT.BORDER);
- textArea.setText(s);
- textArea.setSize(400, 400);
- textArea.setLayoutData("w 500:500,ay top,grow");
- deriveFont(textArea, SWT.BOLD, -1);
-
- return tabbedPane;
- }
-
- public Composite createAPI_Constraints1(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- LC layC = new LC().fill().wrap();
- AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1);
- AC rowC = new AC().align("top", 7).gap("15!", 6).grow(100, 8);
-
- TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout(layC, colC, rowC));
-
- // References to text fields not stored to reduce code clutter.
-
- createList(p1, "Mouse, Mickey", new CC().dockWest().minWidth("150").gapX(null, "10"));
- createLabel(p1, "Last Name", "");
- createTextField(p1, "", "");
- createLabel(p1, "First Name", "");
- createTextField(p1, "", new CC().wrap());
- createLabel(p1, "Phone", "");
- createTextField(p1, "", "");
- createLabel(p1, "Email", "");
- createTextField(p1, "", "");
- createLabel(p1, "Address 1", "");
- createTextField(p1, "", new CC().spanX().growX());
- createLabel(p1, "Address 2", "");
- createTextField(p1, "", new CC().spanX().growX());
- createLabel(p1, "City", "");
- createTextField(p1, "", new CC().wrap());
- createLabel(p1, "State", "");
- createTextField(p1, "", "");
- createLabel(p1, "Postal Code", "");
- createTextField(p1, "", new CC().spanX(2).growX(0));
- createLabel(p1, "Country", "");
- createTextField(p1, "", new CC().wrap());
-
- createButton(p1, "New", new CC().spanX(5).split(5).tag("other"));
- createButton(p1, "Delete", new CC().tag("other"));
- createButton(p1, "Edit", new CC().tag("other"));
- createButton(p1, "Save", new CC().tag("other"));
- createButton(p1, "Cancel", new CC().tag("cancel"));
-
- return tabbedPane;
- }
-
- public Composite createAPI_Constraints2(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- LC layC = new LC().fill().wrap();
- AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1);
- AC rowC = new AC().index(6).gap("15!").align("top").grow(100, 8);
-
- TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout(layC, colC, rowC));
-
- // References to text fields not stored to reduce code clutter.
-
- createLabel(p1, "Last Name", "");
- createTextField(p1, "", "");
- createLabel(p1, "First Name", "");
- createTextField(p1, "", new CC().wrap());
- createLabel(p1, "Phone", "");
- createTextField(p1, "", "");
- createLabel(p1, "Email", "");
- createTextField(p1, "", "");
- createLabel(p1, "Address 1", "");
- createTextField(p1, "", new CC().spanX().growX());
- createLabel(p1, "Address 2", "");
- createTextField(p1, "", new CC().spanX().growX());
- createLabel(p1, "City", "");
- createTextField(p1, "", new CC().wrap());
- createLabel(p1, "State", "");
- createTextField(p1, "", "");
- createLabel(p1, "Postal Code", "");
- createTextField(p1, "", new CC().spanX(2).growX(0));
- createLabel(p1, "Country", "");
- createTextField(p1, "", new CC().wrap());
-
- createButton(p1, "New", new CC().spanX(5).split(5).tag("other"));
- createButton(p1, "Delete", new CC().tag("other"));
- createButton(p1, "Edit", new CC().tag("other"));
- createButton(p1, "Save", new CC().tag("other"));
- createButton(p1, "Cancel", new CC().tag("cancel"));
-
- return tabbedPane;
- }
-
- public Composite createLayout_Showdown(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (pure)", new MigLayout("", "[]15[][grow,fill]15[grow]"));
-
- // References to text fields not stored to reduce code clutter.
-
- createList(p1, "Mouse, Mickey", "spany, growy, wmin 150");
- createLabel(p1, "Last Name", "");
- createTextField(p1, "", "");
- createLabel(p1, "First Name", "split"); // split divides the cell
- createTextField(p1, "", "growx, wrap");
- createLabel(p1, "Phone", "");
- createTextField(p1, "", "");
- createLabel(p1, "Email", "split");
- createTextField(p1, "", "growx, wrap");
- createLabel(p1, "Address 1", "");
- createTextField(p1, "", "span, growx"); // span merges cells
- createLabel(p1, "Address 2", "");
- createTextField(p1, "", "span, growx");
- createLabel(p1, "City", "");
- createTextField(p1, "", "wrap"); // wrap continues on next line
- createLabel(p1, "State", "");
- createTextField(p1, "", "");
- createLabel(p1, "Postal Code", "split");
- createTextField(p1, "", "growx, wrap");
- createLabel(p1, "Country", "");
- createTextField(p1, "", "wrap 15");
-
- createButton(p1, "New", "span, split, align right");
- createButton(p1, "Delete", "");
- createButton(p1, "Edit", "");
- createButton(p1, "Save", "");
- createButton(p1, "Cancel", "wrap push");
-
-
- // Fixed version *******************************************
-
-
- TabItem p2 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout("", "[]15[][grow,fill]15[][grow,fill]"));
-
- // References to text fields not stored to reduce code clutter.
-
- createList(p2, "Mouse, Mickey", "spany, growy, wmin 150");
- createLabel(p2, "Last Name", "");
- createTextField(p2, "", "");
- createLabel(p2, "First Name", "");
- createTextField(p2, "", "wrap");
- createLabel(p2, "Phone", "");
- createTextField(p2, "", "");
- createLabel(p2, "Email", "");
- createTextField(p2, "", "wrap");
- createLabel(p2, "Address 1", "");
- createTextField(p2, "", "span");
- createLabel(p2, "Address 2", "");
- createTextField(p2, "", "span");
- createLabel(p2, "City", "");
- createTextField(p2, "", "wrap");
- createLabel(p2, "State", "");
- createTextField(p2, "", "");
- createLabel(p2, "Postal Code", "");
- createTextField(p2, "", "width 50, grow 0, wrap");
- createLabel(p2, "Country", "");
- createTextField(p2, "", "wrap 15");
-
- createButton(p2, "New", "tag other, span, split");
- createButton(p2, "Delete", "tag other");
- createButton(p2, "Edit", "tag other");
- createButton(p2, "Save", "tag other");
- createButton(p2, "Cancel", "tag cancel, wrap push");
-
- return tabbedPane;
- }
-
- public Composite createDocking(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
- tabbedPane.setLayoutData("grow");
-
- TabItem p1 = createTabPanel(tabbedPane, "Docking 1", new MigLayout("fill"));
-
- createPanel(p1, "1. North", "north");
- createPanel(p1, "2. West", "west");
- createPanel(p1, "3. East", "east");
- createPanel(p1, "4. South", "south");
-
- Table table = new Table(getComposite(p1), DOUBLE_BUFFER);
- for (int i = 0; i < 6; i++) {
- TableColumn tc = new TableColumn(table, SWT.LEFT | SWT.V_SCROLL | SWT.SCROLL_LINE);
- tc.setText("Column " + (i + 1));
- tc.setWidth(100);
- }
-
- for (int r = 0; r < 20; r++) {
- TableItem item1 = new TableItem(table,0);
- String[] data = new String[6];
- for (int c = 0; c < data.length; c++)
- data[c] = "Cell " + (r + 1) + ", " + (c + 1);
- item1.setText(data);
- }
- table.setHeaderVisible(true);
- table.setLinesVisible(true);
- table.setLayoutData("grow");
-
-
- TabItem p2 = createTabPanel(tabbedPane, "Docking 2 (fill)", new MigLayout("fill", "[c]", ""));
-
- createPanel(p2, "1. North", "north");
- createPanel(p2, "2. North", "north");
- createPanel(p2, "3. West", "west");
- createPanel(p2, "4. West", "west");
- createPanel(p2, "5. South", "south");
- createPanel(p2, "6. East", "east");
- createButton(p2, "7. Normal", "");
- createButton(p2, "8. Normal", "");
- createButton(p2, "9. Normal", "");
-
- TabItem p3 = createTabPanel(tabbedPane, "Docking 3", new MigLayout());
-
- createPanel(p3, "1. North", "north");
- createPanel(p3, "2. South", "south");
- createPanel(p3, "3. West", "west");
- createPanel(p3, "4. East", "east");
- createButton(p3, "5. Normal", "");
-
- TabItem p4 = createTabPanel(tabbedPane, "Docking 4", new MigLayout());
-
- createPanel(p4, "1. North", "north");
- createPanel(p4, "2. North", "north");
- createPanel(p4, "3. West", "west");
- createPanel(p4, "4. West", "west");
- createPanel(p4, "5. South", "south");
- createPanel(p4, "6. East", "east");
- createButton(p4, "7. Normal", "");
- createButton(p4, "8. Normal", "");
- createButton(p4, "9. Normal", "");
-
- TabItem p5 = createTabPanel(tabbedPane, "Docking 5 (fillx)", new MigLayout("fillx", "[c]", ""));
-
- createPanel(p5, "1. North", "north");
- createPanel(p5, "2. North", "north");
- createPanel(p5, "3. West", "west");
- createPanel(p5, "4. West", "west");
- createPanel(p5, "5. South", "south");
- createPanel(p5, "6. East", "east");
- createButton(p5, "7. Normal", "");
- createButton(p5, "8. Normal", "");
- createButton(p5, "9. Normal", "");
-
- TabItem p6 = createTabPanel(tabbedPane, "Random Docking", new MigLayout("fill"));
-
- String[] sides = {"north", "east", "south", "west"};
- Random rand = new Random();
- for (int i = 0; i < 20; i++) {
- int side = rand.nextInt(4);
- createPanel(p6, ((i + 1) + " " + sides[side]), sides[side]);
- }
- createPanel(p6, "I'm in the Center!", "grow");
-
- return tabbedPane;
- }
-
- public Control createAbsolute_Position(final Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // Pos tab
- TabItem posTabPanel = createTabPanel(tabbedPane, "X Y Positions", new FillLayout());
- final Composite posPanel = createPanel(posTabPanel, new MigLayout());
-
- createButton(posPanel, "pos 0.5al 0al", null);
- createButton(posPanel, "pos 1al 0al", null);
- createButton(posPanel, "pos 0.5al 0.5al", null);
- createButton(posPanel, "pos 5in 45lp", null);
- createButton(posPanel, "pos 0.5al 0.5al", null);
- createButton(posPanel, "pos 0.5al 1al", null);
- createButton(posPanel, "pos 1al .25al", null);
- createButton(posPanel, "pos visual.x2-pref visual.y2-pref", null);
- createButton(posPanel, "pos 1al -1in", null);
- createButton(posPanel, "pos 100 100", null);
- createButton(posPanel, "pos (10+(20*3lp)) 200", null);
- createButton(posPanel, "Drag Window! (pos 500-container.xpos 500-container.ypos)",
- "pos 500-container.xpos 500-container.ypos");
-
- // Bounds tab
- TabItem boundsTabPanel = createTabPanel(tabbedPane, "X1 Y1 X2 Y2 Bounds", new FillLayout());
- Composite boundsPanel = createPanel(boundsTabPanel, new MigLayout());
-
- Label southLabel = createLabel(boundsPanel, "pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2", null, SWT.CENTER | SWT.BORDER);
- southLabel.setBackground(new Color(display, 200, 200, 255));
- deriveFont(southLabel, SWT.BOLD, 10);
-
- createButton(boundsPanel, "pos 0 0 container.x2 n", null);
- createButton(boundsPanel, "pos visual.x 40 visual.x2 70", null);
- createButton(boundsPanel, "pos visual.x 100 visual.x2 p", null);
- createButton(boundsPanel, "pos 0.1al 0.4al n visual.y2-10", null);
- createButton(boundsPanel, "pos 0.9al 0.4al n visual.y2-10", null);
- createButton(boundsPanel, "pos 0.5al 0.5al, pad 3 0 -3 0", null);
- createButton(boundsPanel, "pos n n 50% 50%", null);
- createButton(boundsPanel, "pos 50% 50% n n", null);
- createButton(boundsPanel, "pos 50% n n 50%", null);
- createButton(boundsPanel, "pos n 50% 50% n", null);
-
- // Glass pane tab
-// final TabItem glassPanel = createTabPanel(tabbedPane, "GlassPane Substitute", parent, new SwtMigLayout("align c c"));
-// final Button butt = new Button("Press me!!");
-// glassPanel.add(butt);
-//
-// butt.addActionListener(new ActionListener() {
-// public void actionPerformed(ActionEvent e)
-// {
-// butt.setEnabled(false);
-// final JPanel bg = new JPanel(parent, new SwtMigLayout("align c c,fill")) {
-// public void paint(Graphics g)
-// {
-// g.setColor(getBackground());
-// g.fillRect(0, 0, getWidth(), getHeight());
-// super.paint(g);
-// }
-// };
-// bg.setOpaque(false);
-// configureActiveComponet(bg);
-//
-// final Label label = createLabel("You don't need a GlassPane to be cool!");
-// label.setFont(label.getFont().deriveFont(30f));
-// label.setForeground(new Color(255, 255, 255, 0));
-// bg.add(label, "align 50% 30%");
-//
-// glassPanel.add(bg, "pos 0 0 visual.x2 visual.y2", 0);
-// final long startTime = System.nanoTime();
-// final long endTime = startTime + 500000000L;
-//
-// glassPanel.revalidate();
-//
-// final javax.swing.Timer timer = new Timer(25, null);
-//
-// timer.addActionListener(new ActionListener() {
-// public void actionPerformed(ActionEvent e)
-// {
-// long now = System.nanoTime();
-// int alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300);
-// if (alpha < 150)
-// bg.setBackground(new Color(100, 100, 100, alpha));
-//
-// if (alpha > 150 && alpha < 405) {
-// label.setForeground(new Color(255, 255, 255, (alpha - 150)));
-// bg.repaint();
-// }
-// if (alpha > 405)
-// timer.stop();
-// }
-// });
-// timer.start();
-// }
-// });
-//
-
- parent.getShell().addControlListener(new ControlAdapter() {
- public void controlMoved(ControlEvent e)
- {
- if (!posPanel.isDisposed()) {
- posPanel.layout();
- } else {
- parent.getShell().removeControlListener(this);
- }
- }
- });
-
- return tabbedPane;
- }
-
- public Control createComponent_Links(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- TabItem linksPanel = createTabPanel(tabbedPane, "Component Links", new MigLayout());
-
- // Links tab
- createButton(linksPanel, "Mini", "pos null ta.y ta.x2 null, pad 3 0 -3 0");
- createTextArea(linksPanel, "Components, Please Link to Me!\nMy ID is: 'ta'", "id ta, pos 0.5al 0.5al, w 300");
- createButton(linksPanel, "id b1,pos ta.x2 ta.y2", null);
- createButton(linksPanel, "pos b1.x2+rel b1.y visual.x2 null", null);
- createCheck(linksPanel, "pos (ta.x+indent) (ta.y2+rel)", null);
- createButton(linksPanel, "pos ta.x2+rel ta.y visual.x2 null", null);
- createButton(linksPanel, "pos null ta.y+(ta.h-pref)/2 ta.x-rel null", null);
- createButton(linksPanel, "pos ta.x ta.y2+100 ta.x2 null", null);
-
- // External tab
- TabItem externalPanel = createTabPanel(tabbedPane, "External Components", new MigLayout());
-
- Button extButt = createButton(externalPanel, "Bounds Externally Set!", "id ext, external");
- extButt.setBounds(250, 130, 200, 40);
- createButton(externalPanel, "pos ext.x2 ext.y2", "pos ext.x2 ext.y2");
- createButton(externalPanel, "pos null null ext.x ext.y", "pos null null ext.x ext.y");
-
- TabItem egTabPanel = createTabPanel(tabbedPane, "End Grouping", new FillLayout());
- final Composite egPanel = createPanel(egTabPanel, new MigLayout());
-
- createButton(egPanel, "id b1, endgroupx g1, pos 200 200", null);
- createButton(egPanel, "id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)", null);
- createButton(egPanel, "id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)", null);
- createButton(egPanel, "id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)", null);
-
- // Group Bounds tab
- TabItem gpTabPanel = createTabPanel(tabbedPane, "Group Bounds", new FillLayout());
- final Composite gpPanel = createPanel(gpTabPanel, new MigLayout());
-
- createButton(gpPanel, "id grp1.b1, pos n 0.5al 50% n", null);
- createButton(gpPanel, "id grp1.b2, pos 50% 0.5al n n", null);
- createButton(gpPanel, "id grp1.b3, pos 0.5al n n b1.y", null);
- createButton(gpPanel, "id grp1.b4, pos 0.5al b1.y2 n n", null);
-
- createButton(gpPanel, "pos n grp1.y2 grp1.x n", null);
- createButton(gpPanel, "pos n n grp1.x grp1.y", null);
- createButton(gpPanel, "pos grp1.x2 n n grp1.y", null);
- createButton(gpPanel, "pos grp1.x2 grp1.y2", null);
-
- Composite boundsPanel = createPanel(gpPanel, (Layout) null);
- boundsPanel.setLayoutData("pos grp1.x grp1.y grp1.x2 grp1.y2");
- boundsPanel.setBackground(new Color(display, 200, 200, 255));
-
- return tabbedPane;
- }
-
- public Control createFlow_Direction(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- createFlowPanel(tabbedPane, "Layout: flowx, Cell: flowx", "", "flowx");
- createFlowPanel(tabbedPane, "Layout: flowx, Cell: flowy", "", "flowy");
- createFlowPanel(tabbedPane, "Layout: flowy, Cell: flowx", "flowy", "flowx");
- createFlowPanel(tabbedPane, "Layout: flowy, Cell: flowy", "flowy", "flowy");
-
- return tabbedPane;
- }
-
- private TabItem createFlowPanel(TabFolder parent, String text, String gridFlow, String cellFlow)
- {
- MigLayout lm = new MigLayout("center, wrap 3," + gridFlow,
- "[110,fill]",
- "[110,fill]");
- TabItem panel = createTabPanel(parent, text, lm);
-
- for (int i = 0; i < 9; i++) {
- Composite b = createPanel(panel, "" + (i + 1), cellFlow);
- Font f = deriveFont(b, SWT.DEFAULT, 20);
- b.getChildren()[0].setFont(f);
- }
-
- Composite b = createPanel(panel, "5:2", cellFlow + ",cell 1 1");
- Font f = deriveFont(b, SWT.DEFAULT, 20);
- b.getChildren()[0].setFont(f);
-
- return panel;
- }
-
- public Control createDebug(Composite parent)
- {
- return createPlainImpl(parent, true);
- }
-
- public Control createButton_Bars(final Composite parent)
- {
- MigLayout lm = new MigLayout("ins 0 0 15lp 0",
- "[grow]",
- "[grow]u[baseline,nogrid]");
-
- final Composite mainPanel = new Composite(parent, DOUBLE_BUFFER);
- mainPanel.setLayout(lm);
-
- TabFolder tabbedPane = new TabFolder(mainPanel, DOUBLE_BUFFER);
- tabbedPane.setLayoutData("grow, wrap");
-
- createButtonBarsPanel(tabbedPane, "Buttons", "help", false);
- createButtonBarsPanel(tabbedPane, "Buttons with Help2", "help2", false);
- createButtonBarsPanel(tabbedPane, "Buttons (Same width)", "help", true);
-
- createLabel(mainPanel, "Button Order:", "");
- final Label formatLabel = createLabel(mainPanel, "", "growx");
- deriveFont(formatLabel, SWT.BOLD , -1);
-
- final Button winButt = createToggleButton(mainPanel, "Windows", "wmin button");
- final Button macButt = createToggleButton(mainPanel, "Mac OS X", "wmin button");
-
- winButt.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent e)
- {
- if (winButt.getSelection()) {
- PlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP);
- formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'");
- macButt.setSelection(false);
- mainPanel.layout();
- }
- }
- });
-
- macButt.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent e)
- {
- if (macButt.getSelection()) {
- PlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX);
- formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'");
- winButt.setSelection(false);
- mainPanel.layout();
- }
- }
- });
-
- Button helpButt = createButton(mainPanel, "Help", "gap unrel,wmin button");
- helpButt.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent e)
- {
- MessageBox msgBox = new MessageBox(parent.getShell());
- msgBox.setMessage("See JavaDoc for PlatformConverter.getButtonBarOrder(..) for details on the format string.");
- msgBox.open();
- }
- });
-
- (PlatformDefaults.getPlatform() == PlatformDefaults.WINDOWS_XP ? winButt : macButt).setSelection(true);
-
- return mainPanel;
- }
-
- private TabItem createButtonBarsPanel(TabFolder parent, String text, String helpTag, boolean sizeLocked)
- {
- MigLayout lm = new MigLayout("nogrid, fillx, aligny 100%, gapy unrel");
- TabItem panel = createTabPanel(parent, text, lm);
-
- // Notice that the order in the rows below does not matter...
- String[][] buttons = new String[][] {
- {"No", "Yes"},
- {"Help", "Close"},
- {"OK", "Help"},
- {"OK", "Cancel", "Help"},
- {"OK", "Cancel", "Apply", "Help"},
- {"No", "Yes", "Cancel"},
- {"Help", "< Move Back", "Move Forward >", "Cancel"},
- {"Print...", "Cancel", "Help"},
- };
-
- for (int r = 0; r < buttons.length; r++) {
- for (int i = 0; i < buttons[r].length; i++) {
- String txt = buttons[r][i];
- String tag = txt;
-
- if (txt.equals("Help")) {
- tag = helpTag;
- } else if (txt.equals("< Move Back")) {
- tag = "back";
- } else if (txt.equals("Close")) {
- tag = "cancel";
- } else if (txt.equals("Move Forward >")) {
- tag = "next";
- } else if (txt.equals("Print...")) {
- tag = "other";
- }
- String wrap = (i == buttons[r].length - 1) ? ",wrap" : "";
- String sizeGroup = sizeLocked ? ("sgx " + r + ",") : "";
- createButton(panel, txt, sizeGroup + "tag " + tag + wrap);
- }
- }
-
- return panel;
- }
-
- public Control createOrientation(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- MigLayout lm = new MigLayout("flowy", "[grow,fill]", "[]0[]15lp[]0[]");
- TabItem mainPanel = createTabPanel(tabbedPane, "Orientation", lm);
-
- // Default orientation
- MigLayout defLM = new MigLayout("", "[][grow,fill]", "");
-
- Composite defPanel = createPanel(mainPanel, defLM);
- addSeparator(defPanel, "Default Orientation");
- createLabel(defPanel, "Level", "");
- createTextField(defPanel, "", "span,growx");
- createLabel(defPanel, "Radar", "");
- createTextField(defPanel, "", "");
- createTextField(defPanel, "", "");
-
- // Right-to-left, Top-to-bottom
- MigLayout rtlLM = new MigLayout("rtl,ttb",
- "[][grow,fill]",
- "");
- Composite rtlPanel = createPanel(mainPanel, rtlLM);
- addSeparator(rtlPanel, "Right to Left");
- createLabel(rtlPanel, "Level", "");
- createTextField(rtlPanel, "", "span,growx");
- createLabel(rtlPanel, "Radar", "");
- createTextField(rtlPanel, "", "");
- createTextField(rtlPanel, "", "");
-
- // Right-to-left, Bottom-to-top
- MigLayout rtlbLM = new MigLayout("rtl,btt",
- "[][grow,fill]",
- "");
- Composite rtlbPanel = createPanel(mainPanel, rtlbLM);
- addSeparator(rtlbPanel, "Right to Left, Bottom to Top");
- createLabel(rtlbPanel, "Level", "");
- createTextField(rtlbPanel, "", "span,growx");
- createLabel(rtlbPanel, "Radar", "");
- createTextField(rtlbPanel, "", "");
- createTextField(rtlbPanel, "", "");
-
- // Left-to-right, Bottom-to-top
- MigLayout ltrbLM = new MigLayout("ltr,btt",
- "[][grow,fill]",
- "");
-
- Composite ltrbPanel = createPanel(mainPanel, ltrbLM);
- addSeparator(ltrbPanel, "Left to Right, Bottom to Top");
- createLabel(ltrbPanel, "Level", "");
- createTextField(ltrbPanel, "", "span,growx");
- createLabel(ltrbPanel, "Radar", "");
- createTextField(ltrbPanel, "", "");
- createTextField(ltrbPanel, "", "");
-
- return tabbedPane;
- }
-
- public Control createCell_Position(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // Absolute grid position
- MigLayout absLM = new MigLayout("",
- "[100:pref,fill]",
- "[100:pref,fill]");
-
- TabItem absPanel = createTabPanel(tabbedPane, "Absolute", absLM);
- createPanel(absPanel, "cell 0 0", null);
- createPanel(absPanel, "cell 2 0", null);
- createPanel(absPanel, "cell 3 0", null);
- createPanel(absPanel, "cell 1 1", null);
- createPanel(absPanel, "cell 0 2", null);
- createPanel(absPanel, "cell 2 2", null);
- createPanel(absPanel, "cell 2 2", null);
-
-
- // Relative grid position with wrap
- MigLayout relAwLM = new MigLayout("wrap",
- "[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]",
- "[100:pref,fill]");
- TabItem relAwPanel = createTabPanel(tabbedPane, "Relative + Wrap", relAwLM);
- createPanel(relAwPanel, "", null);
- createPanel(relAwPanel, "skip", null);
- createPanel(relAwPanel, "", null);
- createPanel(relAwPanel, "skip,wrap", null);
- createPanel(relAwPanel, "", null);
- createPanel(relAwPanel, "skip,split", null);
- createPanel(relAwPanel, "", null);
-
-
- // Relative grid position with manual wrap
- MigLayout relWLM = new MigLayout("",
- "[100:pref,fill]",
- "[100:pref,fill]");
- TabItem relWPanel = createTabPanel(tabbedPane, "Relative", relWLM);
- createPanel(relWPanel, "", null);
- createPanel(relWPanel, "skip", null);
- createPanel(relWPanel, "wrap", null);
- createPanel(relWPanel, "skip,wrap", null);
- createPanel(relWPanel, "", null);
- createPanel(relWPanel, "skip,split", null);
- createPanel(relWPanel, "", null);
-
-
- // Mixed relative and absolute grid position
- MigLayout mixLM = new MigLayout("",
- "[100:pref,fill]",
- "[100:pref,fill]");
- TabItem mixPanel = createTabPanel(tabbedPane, "Mixed", mixLM);
- createPanel(mixPanel, "", null);
- createPanel(mixPanel, "cell 2 0", null);
- createPanel(mixPanel, "", null);
- createPanel(mixPanel, "cell 1 1,wrap", null);
- createPanel(mixPanel, "", null);
- createPanel(mixPanel, "cell 2 2,split", null);
- createPanel(mixPanel, "", null);
-
- return tabbedPane;
- }
-
- public Control createPlain(Composite parent)
- {
- return createPlainImpl(parent, false);
- }
-
- private Control createPlainImpl(Composite parent, boolean debug)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- MigLayout lm = new MigLayout((debug && benchRuns == 0 ? "debug" : ""), "[r][100lp, fill][60lp][95lp, fill]", "");
- TabItem panel = createTabPanel(tabbedPane, "Plain", lm);
-
- addSeparator(panel, "Manufacturer");
- createLabel(panel, "Company", "");
- createTextField(panel, "", "span,growx");
- createLabel(panel, "Contact", "");
- createTextField(panel, "", "span,growx");
- createLabel(panel, "Order No", "");
- createTextField(panel, "", "wmin 15*6,wrap");
-
- addSeparator(panel, "Inspector");
- createLabel(panel, "Name", "");
- createTextField(panel, "", "span,growx");
- createLabel(panel, "Reference No", "");
- createTextField(panel, "", "wrap");
- createLabel(panel, "Status", "");
- createCombo(panel, new String[] {"In Progress", "Finnished", "Released"}, "wrap");
-
- addSeparator(panel, "Ship");
- createLabel(panel, "Shipyard", "");
- createTextField(panel, "", "span,growx");
- createLabel(panel, "Register No", "");
- createTextField(panel, "", "");
- createLabel(panel, "Hull No", "right");
- createTextField(panel, "", "wmin 15*6,wrap");
- createLabel(panel, "Project Type", "");
- createCombo(panel, new String[] {"New Building", "Convention", "Repair"}, "wrap");
-
- if (debug)
- createLabel(panel, "Blue is component bounds. Cell bounds (red) can not be shown in SWT", "newline,ax left,span,gaptop 40");
-
- return tabbedPane;
- }
-
- public Control createBound_Sizes(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1
- String colConstr = i == 0 ? "[right][200]" : "[right, 75lp:pref][200]";
-
- MigLayout LM1 = new MigLayout("wrap", colConstr, "");
- TabItem panel1 = createTabPanel(tabbedPane, i == 0 ? "Jumping 1" : "Stable 2", LM1);
- createLabel(panel1, "File Number:", "");
- createTextField(panel1, "", "growx");
- createLabel(panel1, "RFQ Number:", "");
- createTextField(panel1, "", "growx");
- createLabel(panel1, "Entry Date:", "");
- createTextField(panel1, "", "wmin 6*6");
- createLabel(panel1, "Sales Person:", "");
- createTextField(panel1, "", "growx");
-
- MigLayout LM2 = new MigLayout("wrap", colConstr, "");
- TabItem panel2 = createTabPanel(tabbedPane, i == 0 ? "Jumping 2" : "Stable 2", LM2);
- createLabel(panel2, "Shipper:", "");
- createTextField(panel2, "", "wmin 6*6,split 2");
- createTextField(panel2, "", "growx");
- createLabel(panel2, "Consignee:", "");
- createTextField(panel2, "", "wmin 6*6,split 2");
- createTextField(panel2, "", "growx");
- createLabel(panel2, "Departure:", "");
- createTextField(panel2, "", "wmin 6*6,split 2");
- createTextField(panel2, "", "growx");
- createLabel(panel2, "Destination:", "");
- createTextField(panel2, "", "wmin 6*6,split 2");
- createTextField(panel2, "", "growx");
- }
- return tabbedPane;
- }
-
- public Control createComponent_Sizes(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- MigLayout lm = new MigLayout("wrap", "[right][0:pref,grow]", "");
-
- TabItem tabPanel = createTabPanel(tabbedPane, "Component Sizes", new FillLayout());
-
- SashForm sashForm = new SashForm(getComposite(tabPanel), SWT.HORIZONTAL | SWT.SMOOTH);
- sashForm.setBackground(new Color(display, 50, 50, 50));
-
- Composite panel = createPanel(sashForm, lm);
- createTextArea(sashForm, "Use slider to see how the components grow and shrink depending on the constraints set on them.", "");
-
- createLabel(panel, "", "");
- createTextField(panel, "8 ", "");
- createLabel(panel, "width min!", null);
- createTextField(panel, "3 ", "width min!");
- createLabel(panel, "width pref!", "");
- createTextField(panel, "3 ", "width pref!");
- createLabel(panel, "width min:pref", null);
- createTextField(panel, "8 ", "width min:pref");
- createLabel(panel, "width min:100:150", null);
- createTextField(panel, "8 ", "width min:100:150");
- createLabel(panel, "width min:100:150, growx", null);
- createTextField(panel, "8 ", "width min:100:150, growx");
- createLabel(panel, "width min:100, growx", null);
- createTextField(panel, "8 ", "width min:100, growx");
- createLabel(panel, "width 40!", null);
- createTextField(panel, "8 ", "width 40!");
- createLabel(panel, "width 40:40:40", null);
- createTextField(panel, "8 ", "width 40:40:40");
-
- return tabbedPane;
- }
-
- public Control createCell_Alignments(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // Horizontal
- MigLayout hLM = new MigLayout("wrap",
- "[grow,left][grow,center][grow,right][grow,fill,center]",
- "[]unrel[][]");
- TabItem hPanel = createTabPanel(tabbedPane, "Horizontal", hLM);
- String[] sizes = new String[] {"", "growx", "growx 0", "left", "center", "right", "leading", "trailing"};
- createLabel(hPanel, "[left]", "c");
- createLabel(hPanel, "[center]", "c");
- createLabel(hPanel, "[right]", "c");
- createLabel(hPanel, "[fill,center]", "c, growx 0");
-
- for (int r = 0; r < sizes.length; r++) {
- for (int c = 0; c < 4; c++) {
- String text = sizes[r].length() > 0 ? sizes[r] : "default";
- createButton(hPanel, text, sizes[r]);
- }
- }
-
- // Vertical
- MigLayout vLM = new MigLayout("wrap,flowy",
- "[right][]",
- "[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]");
- TabItem vPanel = createTabPanel(tabbedPane, "Vertical", vLM);
- String[] vSizes = new String[] {"", "growy", "growy 0", "top", "center", "bottom"};
- createLabel(vPanel, "[top]", "center");
- createLabel(vPanel, "[center]", "center");
- createLabel(vPanel, "[bottom]", "center");
- createLabel(vPanel, "[fill, bottom]", "center, growy 0");
- createLabel(vPanel, "[fill, baseline]", "center");
-
- for (int c = 0; c < vSizes.length; c++) {
- for (int r = 0; r < 5; r++) {
- String text = vSizes[c].length() > 0 ? vSizes[c] : "default";
- createButton(vPanel, text, vSizes[c]);
- }
- }
-
- return tabbedPane;
- }
-
- public Control createUnits(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // Horizontal
- MigLayout hLM = new MigLayout("wrap",
- "[right][]",
- "");
- TabItem hPanel = createTabPanel(tabbedPane, "Horizontal", hLM);
- String[] sizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "30sp"};
- for (int i = 0; i < sizes.length; i++) {
- createLabel(hPanel, sizes[i], "");
- createTextField(hPanel, "", "width " + sizes[i] + "");
- }
-
- // Horizontal lp
- MigLayout hlpLM = new MigLayout("", "[right][][]", "");
- TabItem hlpPanel = createTabPanel(tabbedPane, "Horizontal LP", hlpLM);
- createLabel(hlpPanel, "9 cols", "");
- createTextField(hlpPanel, "", "wmin 9*6");
- String[] lpSizes = new String[] {"75lp", "75px", "88px", "100px"};
- createLabel(hlpPanel, "", "wrap");
- for (int i = 0; i < lpSizes.length; i++) {
- createLabel(hlpPanel, lpSizes[i], "");
- createTextField(hlpPanel, "", "width " + lpSizes[i] + ", wrap");
- }
-
- // Vertical
- MigLayout vLM = new MigLayout("wrap,flowy",
- "[c]",
- "[top][top]");
- TabItem vPanel = createTabPanel(tabbedPane, "Vertical", vLM);
- String[] vSizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "30sp"};
- for (int i = 0; i < sizes.length; i++) {
- createLabel(vPanel, vSizes[i], "");
- createTextArea(vPanel, "", "width 50!, height " + vSizes[i] + "");
- }
-
- // Vertical lp
- MigLayout vlpLM = new MigLayout("wrap,flowy",
- "[c]",
- "[top][top]40px[top][top]");
- TabItem vlpPanel = createTabPanel(tabbedPane, "Vertical LP", vlpLM);
- createLabel(vlpPanel, "4 rows", "");
- createTextArea(vlpPanel, "\n\n\n\n", "width 50!");
- createLabel(vlpPanel, "field", "");
- createTextField(vlpPanel, "", "wmin 5*9");
-
- String[] vlpSizes1 = new String[] {"63lp", "57px", "63px", "68px", "25%"};
- String[] vlpSizes2 = new String[] {"21lp", "21px", "23px", "24px", "10%"};
- for (int i = 0; i < vlpSizes1.length; i++) {
- createLabel(vlpPanel, vlpSizes1[i], "");
- createTextArea(vlpPanel, "", "width 50!, height " + vlpSizes1[i] + "");
- createLabel(vlpPanel, vlpSizes2[i], "");
- createTextField(vlpPanel, "", "height " + vlpSizes2[i] + "!,wmin 5*6");
- }
-
- createLabel(vlpPanel, "button", "skip 2");
- createButton(vlpPanel, "...", "");
-
- return tabbedPane;
- }
-
- public Control createGrouping(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // Ungrouped
- MigLayout ugM = new MigLayout("", "[]push[][][]", "");
- TabItem ugPanel = createTabPanel(tabbedPane, "Ungrouped", ugM);
- createButton(ugPanel, "Help", "");
- createButton(ugPanel, "< Back", "gap push");
- createButton(ugPanel, "Forward >", "");
- createButton(ugPanel, "Apply", "gap unrel");
- createButton(ugPanel, "Cancel", "gap unrel");
-
- // Grouped Components
- MigLayout gM = new MigLayout("nogrid, fillx");
- TabItem gPanel = createTabPanel(tabbedPane, "Grouped (Components)", gM);
- createButton(gPanel, "Help", "sg");
- createButton(gPanel, "< Back", "sg, gap push");
- createButton(gPanel, "Forward >", "sg");
- createButton(gPanel, "Apply", "sg, gap unrel");
- createButton(gPanel, "Cancel", "sg, gap unrel");
-
- // Grouped Columns
- MigLayout gcM = new MigLayout("", "[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]", "");
- TabItem gcPanel = createTabPanel(tabbedPane, "Grouped (Columns)", gcM);
- createButton(gcPanel, "Help", "");
- createButton(gcPanel, "< Back", "");
- createButton(gcPanel, "Forward >", "");
- createButton(gcPanel, "Apply", "");
- createButton(gcPanel, "Cancel", "");
-
- // Ungrouped Rows
- MigLayout ugrM = new MigLayout(); // no "sg" is the only difference to next panel
- TabItem ugrPanel = createTabPanel(tabbedPane, "Ungrouped Rows", ugrM);
- createLabel(ugrPanel, "File Number:", "");
- createTextField(ugrPanel, "30 ", "wrap");
- createLabel(ugrPanel, "BL/MBL number:", "");
- createTextField(ugrPanel, "7 ", "split 2");
- createTextField(ugrPanel, "7 ", "wrap");
- createLabel(ugrPanel, "Entry Date:", "");
- createTextField(ugrPanel, "7 ", "wrap");
- createLabel(ugrPanel, "RFQ Number:", "");
- createTextField(ugrPanel, "30 ", "wrap");
- createLabel(ugrPanel, "Goods:", "");
- createCheck(ugrPanel, "Dangerous", "wrap");
- createLabel(ugrPanel, "Shipper:", "");
- createTextField(ugrPanel, "30 ", "wrap");
- createLabel(ugrPanel, "Customer:", "");
- createTextField(ugrPanel, "", "split 2,growx");
- createButton(ugrPanel, "...", "width 60px:pref,wrap");
- createLabel(ugrPanel, "Port of Loading:", "");
- createTextField(ugrPanel, "30 ", "wrap");
- createLabel(ugrPanel, "Destination:", "");
- createTextField(ugrPanel, "30 ", "wrap");
-
- // Grouped Rows
- MigLayout grM = new MigLayout("", "[]", "[sg]"); // "sg" is the only difference to previous panel
- TabItem grPanel = createTabPanel(tabbedPane, "Grouped Rows", grM);
- createLabel(grPanel, "File Number:", "");
- createTextField(grPanel, "30 ","wrap");
- createLabel(grPanel, "BL/MBL number:", "");
- createTextField(grPanel, "7 ","split 2");
- createTextField(grPanel, "7 ", "wrap");
- createLabel(grPanel, "Entry Date:", "");
- createTextField(grPanel, "7 ", "wrap");
- createLabel(grPanel, "RFQ Number:", "");
- createTextField(grPanel, "30 ", "wrap");
- createLabel(grPanel, "Goods:", "");
- createCheck(grPanel, "Dangerous", "wrap");
- createLabel(grPanel, "Shipper:", "");
- createTextField(grPanel, "30 ", "wrap");
- createLabel(grPanel, "Customer:", "");
- createTextField(grPanel, "", "split 2,growx");
- createButton(grPanel, "...", "width 50px:pref,wrap");
- createLabel(grPanel, "Port of Loading:", "");
- createTextField(grPanel, "30 ", "wrap");
- createLabel(grPanel, "Destination:", "");
- createTextField(grPanel, "30 ", "wrap");
-
- return tabbedPane;
- }
-
- public Control createSpan(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // Horizontal span
- MigLayout colLM = new MigLayout("",
- "[fill][25%,fill][105lp!,fill][150px!,fill]",
- "[]15[][]");
- TabItem colPanel = createTabPanel(tabbedPane, "Column Span/Split", colLM);
- createTextField(colPanel, "Col1 [ ]", "");
- createTextField(colPanel, "Col2 [25%]", "");
- createTextField(colPanel, "Col3 [105lp!]", "");
- createTextField(colPanel, "Col4 [150px!]", "wrap");
-
- createLabel(colPanel, "Full Name:", "");
- createTextField(colPanel, "span, growx ", "span,growx");
-
- createLabel(colPanel, "Phone:", "");
- createTextField(colPanel, " ", "span 3, split 5");
- createTextField(colPanel, " ", null);
- createTextField(colPanel, " ", null);
- createTextField(colPanel, " ", null);
- createLabel(colPanel, "(span 3, split 4)", "wrap");
-
- createLabel(colPanel, "Zip/City:", "");
- createTextField(colPanel, " ", "");
- createTextField(colPanel, "span 2, growx", null);
-
- // Vertical span
- MigLayout rowLM = new MigLayout("wrap",
- "[225lp]para[225lp]",
- "[]3[]unrel[]3[]unrel[]3[]");
- TabItem rowPanel = createTabPanel(tabbedPane, "Row Span", rowLM);
- createLabel(rowPanel, "Name", "");
- createLabel(rowPanel, "Notes", "");
- createTextField(rowPanel, "growx", null);
- createTextArea(rowPanel, "spany,grow ", "spany,grow,hmin 13*5");
- createLabel(rowPanel, "Phone", "");
- createTextField(rowPanel, "growx", null);
- createLabel(rowPanel, "Fax", "");
- createTextField(rowPanel, "growx", null);
-
-
- return tabbedPane;
- }
-
- public Control createGrowing(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // All tab
- MigLayout allLM = new MigLayout("",
- "[pref!][grow,fill]",
- "[]15[]");
- TabItem allTab = createTabPanel(tabbedPane, "All", allLM);
- createLabel(allTab, "Fixed", "");
- createLabel(allTab, "Gets all extra space", "wrap");
- createTextField(allTab, " ", "");
- createTextField(allTab, " ", "");
-
- // Half tab
- MigLayout halfLM = new MigLayout("",
- "[pref!][grow,fill]",
- "[]15[]");
- TabItem halfTab = createTabPanel(tabbedPane, "Half", halfLM);
- createLabel(halfTab, "Fixed", "");
- createLabel(halfTab, "Gets half of extra space", "");
- createLabel(halfTab, "Gets half of extra space", "wrap");
- createTextField(halfTab, " ", "");
- createTextField(halfTab, " ", "");
- createTextField(halfTab, " ", "");
-
- // Percent 1 tab
- MigLayout p1LM = new MigLayout("",
- "[pref!][0:0,grow 25,fill][0:0,grow 75,fill]",
- "[]15[]");
- TabItem p1Tab = createTabPanel(tabbedPane, "Percent 1", p1LM);
- createLabel(p1Tab, "Fixed", "");
- createLabel(p1Tab, "Gets 25% of extra space", "");
- createLabel(p1Tab, "Gets 75% of extra space", "wrap");
- createTextField(p1Tab, " ", "");
- createTextField(p1Tab, " ", "");
- createTextField(p1Tab, " ", "");
-
- // Percent 2 tab
- MigLayout p2LM = new MigLayout("",
- "[0:0,grow 33,fill][0:0,grow 67,fill]",
- "[]15[]");
- TabItem p2Tab = createTabPanel(tabbedPane, "Percent 2", p2LM);
- createLabel(p2Tab, "Gets 33% of extra space", "");
- createLabel(p2Tab, "Gets 67% of extra space", "wrap");
- createTextField(p2Tab, " ", "");
- createTextField(p2Tab, " ", "");
-
- // Vertical 1 tab
- MigLayout v1LM = new MigLayout("flowy",
- "[]15[]",
- "[][c,pref!][c,grow 25,fill][c,grow 75,fill]");
- TabItem v1Tab = createTabPanel(tabbedPane, "Vertical 1", v1LM);
- createLabel(v1Tab, "Fixed", "skip");
- createLabel(v1Tab, "Gets 25% of extra space", "");
- createLabel(v1Tab, "Gets 75% of extra space", "wrap");
- createLabel(v1Tab, "new Text(SWT.MULTI | SWT.WRAP | SWT.BORDER)", "");
- createTextArea(v1Tab, "", "hmin 4*13");
- createTextArea(v1Tab, "", "hmin 4*13");
- createTextArea(v1Tab, "", "hmin 4*13");
-
- // Vertical 2 tab
- MigLayout v2LM = new MigLayout("flowy",
- "[]15[]",
- "[][c,grow 33,fill][c,grow 67,fill]");
- TabItem v2Tab = createTabPanel(tabbedPane, "Vertical 2", v2LM);
- createLabel(v2Tab, "Gets 33% of extra space", "skip");
- createLabel(v2Tab, "Gets 67% of extra space", "wrap");
- createLabel(v2Tab, "new Text(SWT.MULTI | SWT.WRAP | SWT.BORDER)", "");
- createTextArea(v2Tab, "", "hmin 4*13");
- createTextArea(v2Tab, "", "hmin 4*13");
-
- return tabbedPane;
- }
-
- public Control createBasic_Sizes(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // Horizontal tab
- MigLayout horLM = new MigLayout("",
- "[]15[75px]25[min]25[]",
- "[]15");
- TabItem horTab = createTabPanel(tabbedPane, "Horizontal - Column size set", horLM);
- createLabel(horTab, "75px", "skip");
- createLabel(horTab, "Min", "");
- createLabel(horTab, "Pref", "wrap");
-
- createLabel(horTab, "new Text(15)", "");
- createTextField(horTab, "", "wmin 10");
- createTextField(horTab, "", "wmin 10");
- createTextField(horTab, "", "wmin 10");
-
- // Vertical tab 1
- MigLayout verLM = new MigLayout("flowy,wrap",
- "[]15[]",
- "[]15[c,45:45]15[c,min]15[c,pref]");
- TabItem verTab = createTabPanel(tabbedPane, "\"Vertical - Row sized\"", verLM);
- createLabel(verTab, "45px", "skip");
- createLabel(verTab, "Min", "");
- createLabel(verTab, "Pref", "");
-
- createLabel(verTab, "new Text(SWT.MULTI)", "");
- createTextArea(verTab, "", "");
- createTextArea(verTab, "", "");
- createTextArea(verTab, "", "");
-
- // Componentsized/Baseline 2
- MigLayout verLM2 = new MigLayout("flowy,wrap",
- "[]15[]",
- "[]15[baseline]15[baseline]15[baseline]");
- TabItem verTab2 = createTabPanel(tabbedPane, "\"Vertical - Component sized + Baseline\"", verLM2);
- createLabel(verTab2, "45px", "skip");
- createLabel(verTab2, "Min", "");
- createLabel(verTab2, "Pref", "");
-
- createLabel(verTab2, "new Text(SWT.MULTI)", "");
- createTextArea(verTab2, "", "height 45");
- createTextArea(verTab2, "", "height min");
- createTextArea(verTab2, "", "height pref");
-
- return tabbedPane;
- }
-
- public Control createAlignments(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // Horizontal tab
- MigLayout horLM = new MigLayout("wrap",
- "[label]15[left]15[center]15[right]15[fill]15[]",
- "[]15[]");
-
- String[] horLabels = new String[] {"[label]", "[left]", "[center]", "[right]", "[fill]", "[] (Default)"};
- TabItem horTab = createTabPanel(tabbedPane, "Horizontal", horLM);
- String[] horNames = new String[] {"First Name", "Phone Number", "Facsmile", "Email", "Address", "Other"};
- for (int c = 0; c < horLabels.length; c++)
- createLabel(horTab, horLabels[c], "");
-
- for (int r = 0; r < horLabels.length; r++) {
- for (int c = 0; c < horNames.length; c++) {
- if (c == 0) {
- createLabel(horTab, horNames[r] + ":", "");
- } else {
- createButton(horTab, horNames[r], "");
- }
- }
- }
-
- // Vertical tab
- MigLayout verLM = new MigLayout("wrap,flowy",
- "[]unrel[]rel[]",
- "[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]");
-
- String[] verLabels = new String[] {"[top]", "[center]", "[bottom]", "[fill]", "[fill,baseline]", "[baseline]", "[] (Default)"};
- TabItem verTab = createTabPanel(tabbedPane, "Vertical", verLM);
-
- for (int c = 0; c < verLabels.length; c++)
- createLabel(verTab, verLabels[c], "");
-
- for (int c = 0; c < verLabels.length; c++)
- createButton(verTab, "A Button", "");
-
- for (int c = 0; c < verLabels.length; c++)
- createTextField(verTab, "JTextFied", "");
-
- for (int c = 0; c < verLabels.length; c++)
- createTextArea(verTab, "Text ", "");
-
- for (int c = 0; c < verLabels.length; c++)
- createTextArea(verTab, "Text\nwith two lines", "");
-
- for (int c = 0; c < verLabels.length; c++)
- createTextArea(verTab, "Scrolling Text\nwith two lines", "");
-
- return tabbedPane;
- }
-
- public Control createQuick_Start(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- MigLayout lm = new MigLayout("wrap",
- "[right][fill,sizegroup]unrel[right][fill,sizegroup]",
- "");
-
- TabItem p = createTabPanel(tabbedPane, "Quick Start", lm);
-
- addSeparator(p, "General");
- createLabel(p, "Company", "gap indent");
- createTextField(p, "", "span,growx");
- createLabel(p, "Contact", "gap indent");
- createTextField(p, "", "span,growx");
-
- addSeparator(p, "Propeller");
- createLabel(p, "PTI/kW", "gap indent");
- createTextField(p, "", "wmin 100");
- createLabel(p, "Power/kW", "gap indent");
- createTextField(p, "", "wmin 100");
- createLabel(p, "R/mm", "gap indent");
- createTextField(p, "", "wmin 100");
- createLabel(p, "D/mm", "gap indent");
- createTextField(p, "", "wmin 100");
-
- return tabbedPane;
- }
-
- public Control createGrow_Shrink(Composite parent)
- {
- TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER);
-
- // shrink tab
- MigLayout slm = new MigLayout("nogrid");
- TabItem shrinkTabPanel = createTabPanel(tabbedPane, "Shrink", new FillLayout());
-
-
- SashForm shrinkSash = new SashForm(getComposite(shrinkTabPanel), SWT.HORIZONTAL | SWT.SMOOTH);
- shrinkSash.setBackground(new Color(display, 100, 100, 100));
-
- Composite shrinkPanel = createPanel(shrinkSash, slm);
- shrinkPanel.setLayoutData("wmin 100");
-
- createTextField(shrinkPanel, "shp 110", "shp 110,w 10:130");
- createTextField(shrinkPanel, "Default (100)", "w 10:130");
- createTextField(shrinkPanel, "shp 90", "shp 90,w 10:130");
-
- createTextField(shrinkPanel, "shrink 25", "newline,shrink 25,w 10:130");
- createTextField(shrinkPanel, "shrink 75", "shrink 75,w 10:130");
-
- createTextField(shrinkPanel, "Default", "newline, w 10:130");
- createTextField(shrinkPanel, "Default", "w 10:130");
-
- createTextField(shrinkPanel, "shrink 0", "newline,shrink 0,w 10:130");
-
- createTextField(shrinkPanel, "shp 110", "newline,shp 110,w 10:130");
- createTextField(shrinkPanel, "shp 100,shrink 25", "shp 100,shrink 25,w 10:130");
- createTextField(shrinkPanel, "shp 100,shrink 75", "shp 100,shrink 75,w 10:130");
-
- createTextArea(shrinkSash, "Use the slider to see how the components shrink depending on the constraints set on them.\n\n'shp' means Shrink Priority. " +
- "Lower values will be shrunk before higer ones and the default value is 100.\n\n'shrink' means Shrink Weight. " +
- "Lower values relative to other's means they will shrink less when space is scarse. " +
- "Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\n\n" +
- "The component's minimum size will always be honored.\n\nFor SWT, which doesn't have a component notion of minimum, " +
- "preferred or maximum size, those sizes are set explicitly to minimum 10 and preferred 130 pixels.", "");
-
- // Grow tab
- TabItem growTabPanel = createTabPanel(tabbedPane, "Grow", new FillLayout());
-
- SashForm growSash = new SashForm(getComposite(growTabPanel), SWT.HORIZONTAL | SWT.SMOOTH);
- growSash.setBackground(new Color(display, 100, 100, 100));
-
- Composite growPanel = createPanel(growSash, new MigLayout("nogrid", "[grow]"));
- growPanel.setLayoutData("wmin 100");
-
- createButton(growPanel, "gp 110, grow", "gp 110, grow, wmax 170");
- createButton(growPanel, "Default (100), grow", "grow, wmax 170");
- createButton(growPanel, "gp 90, grow", "gp 90, grow, wmax 170");
-
- createButton(growPanel, "Default Button", "newline");
-
- createButton(growPanel, "growx", "newline,growx,wrap");
-
- createButton(growPanel, "gp 110, grow", "gp 110, grow, wmax 170");
- createButton(growPanel, "gp 100, grow 25", "gp 100, grow 25, wmax 170");
- createButton(growPanel, "gp 100, grow 75", "gp 100, grow 75, wmax 170");
-
- createTextArea(growSash, "'gp' means Grow Priority. " +
- "Lower values will be grown before higher ones and the default value is 100.\n\n'grow' means Grow Weight. " +
- "Higher values relative to other's means they will grow more when space is up for takes. " +
- "Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means " +
- "components will normally not grow. \n\nNote that the buttons in the first and last row have max width set to 170 to " +
- "emphasize Grow Priority.\n\nThe component's maximum size will always be honored.", "");
-
- return tabbedPane;
- }
-
-
- // **********************************************************
- // * Helper Methods
- // **********************************************************
-
-// private final ToolTipListener toolTipListener = new ToolTipListener();
-// private final ConstraintListener constraintListener = new ConstraintListener();
-
- private Combo createCombo(Object parent, String[] texts, Object layout)
- {
- Combo b = new Combo(getComposite(parent), SWT.DROP_DOWN);
- for (int i = 0; i < texts.length; i++)
- b.add(texts[i]);
- b.setLayoutData(layout);
-
-// configureActiveComponet(b);
-
- return b;
- }
-
- private Label createLabel(Object parent, String text, Object layout)
- {
- return createLabel(parent, text, layout, SWT.LEFT);
- }
-
- private Label createLabel(Object parent, String text, Object layout, int style)
- {
- final Label b = new Label(getComposite(parent), style | DOUBLE_BUFFER);
- b.setText(text);
- b.setLayoutData(layout != null ? layout : text);
-// b.setAlignment();
-
-// configureActiveComponet(b);
-
- return b;
- }
-
- private Text createTextField(Object parent, String text, Object layout)
- {
- final Text b = new Text(getComposite(parent), SWT.SINGLE | SWT.BORDER | DOUBLE_BUFFER);
- b.setText(text);
- b.setLayoutData(layout != null ? layout : text);
-
-// configureActiveComponet(b);
-
- return b;
- }
-
- private Button createButton(Object parent, String text, Object layout)
- {
- return createButton(getComposite(parent), text, layout, false);
- }
-
- private Button createButton(Object parent, String text, Object layout, boolean bold)
- {
- Button b = new Button(getComposite(parent), SWT.PUSH | SWT.NO_BACKGROUND | DOUBLE_BUFFER);
- b.setText(text.length() == 0 ? "\"\"" : text);
- b.setLayoutData(layout != null ? layout : text);
-
-// configureActiveComponet(b);
-
- return b;
- }
-
- private Composite createPanel(Object parent, String text, Object layout)
- {
- Color bg = new Color(display.getActiveShell().getDisplay(), 255, 255, 255);
- Composite panel = new Composite(getComposite(parent), DOUBLE_BUFFER | SWT.BORDER);
- panel.setLayout(new MigLayout("fill"));
- panel.setBackground(bg);
- panel.setLayoutData(layout != null ? layout : text);
- text = text.length() == 0 ? "\"\"" : text;
- Label label = createLabel(panel, text, "grow", SWT.NO_BACKGROUND | SWT.CENTER);
- label.setBackground(bg);
-
-// configureActiveComponet(panel);
-
- return panel;
- }
-
- private TabItem createTabPanel(TabFolder parent, String text, Layout lm)
- {
- Composite panel = new Composite(parent, DOUBLE_BUFFER);
-// panel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
- TabItem tab = new TabItem(parent, DOUBLE_BUFFER);
- tab.setControl(panel);
- tab.setText(text);
- if (lm != null)
- panel.setLayout(lm);
-
-// configureActiveComponet(panel);
- return tab;
- }
-
- private Composite createPanel(Object parent, Layout lm)
- {
- Composite panel = new Composite(getComposite(parent), DOUBLE_BUFFER);
- panel.setLayout(lm);
-
-// configureActiveComponet(panel);
-
- return panel;
- }
-
- private Button createToggleButton(Object parent, String text, Object layout)
- {
- Button b = new Button(getComposite(parent), SWT.TOGGLE | DOUBLE_BUFFER);
- b.setText(text.length() == 0 ? "\"\"" : text);
- b.setLayoutData(layout != null ? layout : text);
-
-// configureActiveComponet(b);
-
- return b;
- }
-
- private Button createCheck(Object parent, String text, Object layout)
- {
- Button b = new Button(getComposite(parent), SWT.CHECK | DOUBLE_BUFFER);
- b.setText(text);
- b.setLayoutData(layout != null ? layout : text);
-// configureActiveComponet(b);
-
- return b;
- }
-
- private List createList(Object parent, String text, Object layout)
- {
- List list = new List(getComposite(parent), DOUBLE_BUFFER | SWT.BORDER);
- list.add(text);
- list.setLayoutData(layout);
- return list;
- }
-
- private StyledText createTextArea(Object parent, String text, String layout)
- {
- return createTextArea(parent, text, layout, SWT.MULTI | SWT.WRAP | SWT.BORDER | DOUBLE_BUFFER);
- }
-
- private StyledText createTextArea(Object parent, String text, String layout, int style)
- {
- StyledText ta = new StyledText(getComposite(parent), SWT.MULTI | SWT.WRAP | style | DOUBLE_BUFFER);
- ta.setText(text);
- ta.setLayoutData(layout != null ? layout : text);
-
-// configureActiveComponet(ta);
-
- return ta;
- }
-
- public Composite getComposite(Object c)
- {
- if (c instanceof Control)
- return (Composite) c;
-
- return (Composite) ((TabItem) c).getControl();
- }
-
- private Font deriveFont(Control cont, int style, int height)
- {
- Font f = cont.getFont();
- FontData fd = f.getFontData()[0];
- if (style != SWT.DEFAULT)
- fd.setStyle(style);
-
- if (height != -1)
- fd.setHeight(height);
-
- Font font = new Font(display, fd);
- cont.setFont(font);
- return font;
- }
-
-// private Control configureActiveComponet(Control c)
-// {
-// c.addMouseMotionListener(toolTipListener);
-// c.addMouseListener(constraintListener);
-// return c;
-// }
-
- private void addSeparator(Object panel, String text)
- {
- Label l = createLabel(panel, text, "gaptop para, span, split 2");
- l.setForeground(new Color(display, 0, 70, 213));
-
- Label s = new Label(getComposite(panel), SWT.SEPARATOR | SWT.HORIZONTAL | DOUBLE_BUFFER);
- s.setLayoutData("gapleft rel, gaptop para, growx");
-
-// configureActiveComponet(s);
- }
-
-// private class ConstraintListener extends MouseAdapter
-// {
-// public void mousePressed(MouseEvent e)
-// {
-// if (e.isPopupTrigger())
-// react(e);
-// }
-//
-// public void mouseReleased(MouseEvent e)
-// {
-// if (e.isPopupTrigger())
-// react(e);
-// }
-//
-// public void react(MouseEvent e)
-// {
-// Control c = (Control) e.getSource();
-// LayoutManager lm = c.getParent().getLayout();
-// if (lm instanceof SwtMigLayout == false)
-// lm = c.getLayout();
-//
-// if (lm instanceof SwtMigLayout) {
-// MigLayout ffl = (MigLayout) lm;
-// boolean isComp = ffl.isManagingComponent(c);
-// String compConstr = isComp ? ffl.getComponentConstraints(c) : null;
-// String rowsConstr = isComp ? null : ffl.getRowConstraints();
-// String colsConstr = isComp ? null : ffl.getColumnConstraints();
-// String layoutConstr = isComp ? null : ffl.getLayoutConstraints();
-//
-// ConstraintsDialog cDlg = new ConstraintsDialog(SwingDemo.this, layoutConstr, rowsConstr, colsConstr, compConstr);
-// cDlg.pack();
-// cDlg.setLocationRelativeTo(c);
-//
-// if (cDlg.showDialog()) {
-// try {
-// if (isComp) {
-// String constrStr = cDlg.componentConstrTF.getText().trim();
-// ffl.setComponentConstraints(c, constrStr);
-// if (c instanceof Button) {
-// c.setFont(BUTT_FONT);
-// ((Button) c).setText(constrStr.length() == 0 ? "<Empty>" : constrStr);
-// }
-// } else {
-// ffl.setLayoutConstraints(cDlg.layoutConstrTF.getText());
-// ffl.setRowConstraints(cDlg.rowsConstrTF.getText());
-// ffl.setColumnConstraints(cDlg.colsConstrTF.getText());
-// }
-// } catch(Exception ex) {
-// StringWriter sw = new StringWriter();
-// ex.printStackTrace(new PrintWriter(sw));
-// JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(c), sw.toString(), "Error parsing Constraint!", JOptionPane.ERROR_MESSAGE);
-// return;
-// }
-//
-// c.invalidate();
-// c.getParent().validate();
-// }
-// }
-// }
-// }
-//
-// private static class ToolTipListener extends MouseMotionAdapter
-// {
-// public void mouseMoved(MouseEvent e)
-// {
-// Control c = (Control) e.getSource();
-// LayoutManager lm = c.getParent().getLayout();
-// if (lm instanceof SwtMigLayout) {
-// String constr = ((MigLayout) lm).getComponentConstraints(c);
-// c.setToolTipText((constr != null ? ("\"" + constr + "\"") : "null"));
-// }
-// }
-// }
-//
-// private static class ConstraintsDialog extends JDialog implements ActionListener, KeyEventDispatcher
-// {
-// private static final Color ERROR_COLOR = new Color(255, 180, 180);
-// private final JPanel mainPanel = new JPanel(parent, new SwtMigLayout("fillx,flowy,ins dialog",
-// "[fill]",
-// "2[]2"));
-// final Text layoutConstrTF;
-// final Text rowsConstrTF;
-// final Text colsConstrTF;
-// final Text componentConstrTF;
-//
-// private final Button okButt = new Button("OK");
-// private final Button cancelButt = new Button("Cancel");
-//
-// private boolean okPressed = false;
-//
-// public ConstraintsDialog(Frame owner, String layoutConstr, String rowsConstr, String colsConstr, String compConstr)
-// {
-// super(owner, (compConstr != null ? "Edit Component Constraints" : "Edit Container Constraints"), true);
-//
-// layoutConstrTF = createConstraintField(layoutConstr);
-// rowsConstrTF = createConstraintField(rowsConstr);
-// colsConstrTF = createConstraintField(colsConstr);
-// componentConstrTF = createConstraintField(compConstr);
-//
-// if (componentConstrTF != null) {
-// mainPanel.add(new Label("Component Constraints"));
-// mainPanel.add(componentConstrTF);
-// }
-//
-// if (layoutConstrTF != null) {
-// mainPanel.add(new Label("Container Layout Constraints"));
-// mainPanel.add(layoutConstrTF);
-// }
-//
-// if (rowsConstrTF != null) {
-// mainPanel.add(new Label("Container Row Constraints"), "gaptop unrel");
-// mainPanel.add(rowsConstrTF);
-// }
-//
-// if (colsConstrTF != null) {
-// mainPanel.add(new Label("Container Column Constraints"), "gaptop unrel");
-// mainPanel.add(colsConstrTF);
-// }
-//
-// mainPanel.add(okButt, "tag ok,split,flowx,gaptop 15");
-// mainPanel.add(cancelButt, "tag cancel,gaptop 15");
-//
-// setContentPane(mainPanel);
-//
-// okButt.addActionListener(this);
-// cancelButt.addActionListener(this);
-// }
-//
-// public void addNotify()
-// {
-// super.addNotify();
-// KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
-// }
-//
-// public void removeNotify()
-// {
-// KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this);
-// super.removeNotify();
-// }
-//
-// public boolean dispatchKeyEvent(KeyEvent e)
-// {
-// if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
-// dispose();
-// return false;
-// }
-//
-// public void actionPerformed(ActionEvent e)
-// {
-// if (e.getSource() == okButt)
-// okPressed = true;
-// dispose();
-// }
-//
-// private Text createConstraintField(String text)
-// {
-// if (text == null)
-// return null;
-//
-// final Text tf = new Text(text, 50);
-// tf.setFont(new Font("monospaced", Font.PLAIN, 12));
-//
-// tf.addKeyListener(new KeyAdapter() {
-// public void keyPressed(KeyEvent e)
-// {
-// if (e.getKeyCode() == KeyEvent.VK_ENTER) {
-// okButt.doClick();
-// return;
-// }
-//
-// javax.swing.Timer timer = new Timer(50, new ActionListener() {
-// public void actionPerformed(ActionEvent e)
-// {
-// String constr = tf.getText();
-// try {
-// if (tf == layoutConstrTF) {
-// MigLayout.validateLayoutConstraint(constr);
-// } else if (tf == rowsConstrTF) {
-// MigLayout.validateRowConstraints(constr);
-// } else if (tf == colsConstrTF) {
-// MigLayout.validateColumnConstraints(constr);
-// } else if (tf == componentConstrTF) {
-// MigLayout.validateComponentConstraint(constr);
-// }
-// tf.setBackground(Color.WHITE);
-// okButt.setEnabled(true);
-// } catch(Exception ex) {
-// tf.setBackground(ERROR_COLOR);
-// okButt.setEnabled(false);
-// }
-// }
-// });
-// timer.setRepeats(false);
-// timer.start();
-// }
-// });
-//
-// return tf;
-// }
-//
-// private boolean showDialog()
-// {
-// setVisible(true);
-// return okPressed;
-// }
-// }
-
-}
-
-
-
-
+package net.miginfocom.demo; + +import net.miginfocom.layout.*; +import net.miginfocom.swt.MigLayout; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.*; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.Random; + +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ +public class SwtDemo +{ + public static final int SELECTED_INDEX = 0; + + private static final String[][] panels = new String[][] { +// {"Test", "Test, Disregard"}, + {"Welcome", "\n\n \"MigLayout makes complex layouts easy and normal layouts one-liners.\""}, + {"Quick Start", "This is an example of how to build a common dialog type. Note that there are no special components, nested panels or absolute references to cell positions. If you look at the source code you will see that the layout code is very simple to understand."}, + {"Plain", "A simple example on how simple it is to create normal forms. No builders needed since the whole layout manager works like a builder."}, + {"Alignments", "Shows how the alignment of components are specified. At the top/left is the alignment for the column/row. The components have no alignments specified.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."}, + {"Cell Alignments", "Shows how components are aligned when both column/row alignments and component constraints are specified. At the top/left are the alignment for the column/row and the text on the buttons is the component constraint that will override the column/row alignment if it is an alignment.\n\nNote that baseline alignment will be interpreted as 'center' before JDK 6."}, + {"Basic Sizes", "A simple example that shows how to use the column or row min/preferred/max size to set the sizes of the contained components and also an example that shows how to do this directly in the component constraints."}, + {"Growing", "A simple example that shows how to use the growx and growy constraint to set the sizes and how they should grow to fit the available size. Both the column/row and the component grow/shrink constraints can be set, but the components will always be confined to the space given by its column/row."}, + {"Grow Shrink", "Demonstrates the very flexible grow and shrink constraints that can be set on a component.\nComponents can be divided into grow/shrink groups and also have grow/shrink weight within each of those groups.\n\nBy default " + + "components shrink to their inherent (or specified) minimum size, but they don't grow."}, + {"Span", "This example shows the powerful spanning and splitting that can be specified in the component constraints. With spanning any number of cells can be merged with the additional option to split that space for more than one component. This makes layouts very flexible and reduces the number of times you will need nested panels to very few."}, + {"Flow Direction", "Shows the different flow directions. Flow direction for the layout specifies if the next cell will be in the x or y dimension. Note that it can be a different flow direction in the slit cell (the middle cell is slit in two). Wrap is set to 3 for all panels."}, + {"Grouping", "Sizes for both components and columns/rows can be grouped so they get the same size. For instance buttons in a button bar can be given a size-group so that they will all get " + + "the same minimum and preferred size (the largest within the group). Size-groups can be set for the width, height or both."}, + {"Units", "Demonstrates the basic units that are understood by MigLayout. These units can be extended by the user by adding one or more UnitConverter(s)."}, + {"Component Sizes", "Minimum, preferred and maximum component sizes can be overridden in the component constraints using any unit type. The format to do this is short and simple to understand. You simply specify the " + + "min, preferred and max sizes with a colon between.\n\nAbove are some examples of this. An exclamation mark means that the value will be used for all sizes."}, + {"Bound Sizes", "Shows how to create columns that are stable between tabs using minimum sizes."}, + {"Cell Position", "Even though MigLayout has automatic grid flow you can still specify the cell position explicitly. You can even combine absolute (x, y) and flow (skip, wrap and newline) constraints to build your layout."}, + {"Orientation", "MigLayout supports not only right-to-left orientation, but also bottom-to-top. You can even set the flow direction so that the flow is vertical instead of horizontal. It will automatically " + + "pick up if right-to-left is to be used depending on the ComponentWrapper, but it can also be manually set for every layout."}, + {"Absolute Position", "Demonstrates the option to place any number of components using absolute coordinates. This can be just the position (if min/preferred size) using \"x y p p\" format or" + + "the bounds using the \"x1 y1 x2 y2\" format. Any unit can be used and percent is relative to the parent.\nAbsolute components will not disturb the flow or occupy cells in the grid. " + + "Absolute positioned components will be taken into account when calculating the container's preferred size."}, + {"Component Links", "Components can be linked to any side of any other component. It can be a forward, backward or cyclic link references, as long as it is stable and won't continue to change value over many iterations." + + "Links are referencing the ID of another component. The ID can be overridden by the component's constrains or is provided by the ComponentWrapper. For instance it will use the component's 'name' on Swing.\n" + + "Since the links can be combined with any expression (such as 'butt1.x+10' or 'max(button.x, 200)' the links are very customizable."}, + {"Docking", "Docking components can be added around the grid. The docked component will get the whole width/height on the docked side by default, however this can be overridden. When all docked components are laid out, whatever space " + + "is left will be available for the normal grid laid out components. Docked components does not in any way affect the flow in the grid.\n\nSince the docking runs in the same code path " + + "as the normal layout code the same properties can be specified for the docking components. You can for instance set the sizes and alignment or link other components to their docked component's bounds."}, + {"Button Bars", "Button order is very customizable and are by default different on the supported platforms. E.g. Gaps, button order and minimum button size are properties that are 'per platform'. MigLayout picks up the current platform automatically and adjusts the button order and minimum button size accordingly, all without using a button builder or any other special code construct."}, + {"Debug", "Demonstrates the non-intrusive way to get visual debugging aid. There is no need to use a special DebugPanel or anything that will need code changes. The user can simply turn on debug on the layout manager by using the debug constraint and it will " + + "continuously repaint the panel with debug information on top. This means you don't have to change your code to debug!"}, + {"Layout Showdown", "This is an implementation of the Layout Showdown posted on java.net by John O'Conner. The first tab is a pure implemenetation of the showdown that follows all the rules. The second tab is a slightly fixed version that follows some improved layout guidelines." + + "The source code is for bothe the first and for the fixed version. Note the simplification of the code for the fixed version. Writing better layouts with MiG Layout is reasier that writing bad.\n\nReference: http://weblogs.java.net/blog/joconner/archive/2006/10/more_informatio.html"}, + {"API Constraints1", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."}, + {"API Constraints2", "This dialog shows the constraint API added to v2.0. It works the same way as the string constraints but with chained method calls. See the source code for details."}, + }; + + private static int DOUBLE_BUFFER = 0;//SWT.DOUBLE_BUFFERED; + + private static int benchRuns = 0; + private static long startupMillis = 0; + private static long timeToShowMillis = 0; + private static long benchRunTime = 0; + private static String benchOutFileName = null; + private static boolean append = false; + + private static long lastRunTimeStart = 0; + private static StringBuffer runTimeSB = null; + + private static Display display = null; + + public static void main(String[] args) + { + startupMillis = System.currentTimeMillis(); + + if (args.length > 0) { + for (int i = 0; i < args.length; i++) { + String arg = args[i].trim(); + if (arg.startsWith("-bench")) { + benchRuns = 10; + try { + if (arg.length() > 6) + benchRuns = Integer.parseInt(arg.substring(6)); + } catch (Exception ex) {} + } else if (arg.startsWith("-bout")) { + benchOutFileName = arg.substring(5); + } else if (arg.startsWith("-append")) { + append = true; + } else if (arg.startsWith("-verbose")) { + runTimeSB = new StringBuffer(256); + } else { + System.out.println("Usage: [-bench[#_of_runs]] [-bout[benchmark_results_filename]] [-append]\n" + + " -bench Run demo as benchmark. Run count can be appended. 10 is default.\n" + + " -bout Benchmark results output filename.\n" + + " -append Appends the result to the \"-bout\" file.\n" + + " -verbose Print the times of every run.\n" + + "\nExamples:\n" + + " java -jar swtdemoapp.jar -bench -boutC:/bench.txt -append\n" + + " java -jar swtdemoapp.jar -bench20\n" + + "NOTE! swt-win32-3232.dll must be in the current directory!"); + System.exit(0); + } + } + } + + if (benchRuns > 0) + LayoutUtil.setDesignTime(null, true); + + new SwtDemo(); + } + + final List pickerList; + final Composite layoutDisplayPanel; + final StyledText descrTextArea; + + public SwtDemo() + { + display = new Display(); + final Shell shell = new Shell(); + + shell.setLayout(new MigLayout("wrap", "[]u[grow,fill]", "[grow,fill][pref!]")); + shell.setText("MigLayout SWT Demo v2.5 - Mig Layout v" + LayoutUtil.getVersion()); + + TabFolder layoutPickerTabPane = new TabFolder(shell, DOUBLE_BUFFER); + layoutPickerTabPane.setLayoutData("spany,grow"); + pickerList = new List(layoutPickerTabPane, SWT.SINGLE | DOUBLE_BUFFER); + deriveFont(pickerList, SWT.BOLD, -1); + TabItem tab = new TabItem(layoutPickerTabPane, DOUBLE_BUFFER); + tab.setControl(pickerList); + tab.setText("Example Browser"); + for (int i = 0; i < panels.length; i++) + pickerList.add(panels[i][0]); + + layoutDisplayPanel = new Composite(shell, DOUBLE_BUFFER); + layoutDisplayPanel.setLayout(new MigLayout("fill, insets 0")); + + TabFolder descriptionTabPane = new TabFolder(shell, DOUBLE_BUFFER); + descriptionTabPane.setLayoutData("growx,hmin 120,w 500:500"); + descrTextArea = createTextArea(descriptionTabPane, "", "", SWT.MULTI | SWT.WRAP); + tab = new TabItem(descriptionTabPane, DOUBLE_BUFFER); + tab.setControl(descrTextArea); + tab.setText("Description"); + + pickerList.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + dispatchSelection(); + } + }); + + shell.setSize(900, 650); + shell.open(); + + shell.layout(); + + + if (benchRuns > 0) { + doBenchmark(); + } else { + pickerList.select(SELECTED_INDEX); + dispatchSelection(); + + display.addFilter(SWT.KeyDown, new Listener() { + + public void handleEvent(Event e) + { + if (e.character == 'b') { + startupMillis = System.currentTimeMillis(); + timeToShowMillis = System.currentTimeMillis() - startupMillis; + benchRuns = 1; + doBenchmark(); + } + } + }); + } + + while(!shell.isDisposed()){ + if(!display.readAndDispatch()) + display.sleep(); + } + + display.dispose(); + } + + private static Control[] comps = null; // thread hack... + private static Control[] tabs = null; // thread hack... + + private void doBenchmark() + { + final int pCnt = pickerList.getItemCount(); + Thread benchThread = new Thread() { + public void run() + { + for (int j = 0; j < benchRuns; j++) { + lastRunTimeStart = System.currentTimeMillis(); + final int jj = j; + for (int i = 0; i < pCnt; i++) { + final int ii = i; + try { + display.syncExec(new Runnable() { + public void run () { + pickerList.setSelection(ii); + dispatchSelection(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + + display.syncExec(new Runnable() { + public void run() { + comps = layoutDisplayPanel.getChildren(); + } + }); + + for (int cIx = 0; cIx < comps.length; cIx++) { + + if (comps[cIx] instanceof TabFolder) { + final TabFolder tp = (TabFolder) comps[cIx]; + + display.syncExec(new Runnable() { + public void run() { + tabs = tp.getTabList(); + } + }); + + for (int k = 0; k < tabs.length; k++) { + final int kk = k; + try { + display.syncExec(new Runnable() { + public void run() { + tp.setSelection(kk); + + if (timeToShowMillis == 0) + timeToShowMillis = System.currentTimeMillis() - startupMillis; + } + }); + } catch (Exception e) { + e.printStackTrace(); + }; + } + } + } + } + if (runTimeSB != null) { + runTimeSB.append("Run ").append(jj).append(": "); + runTimeSB.append(System.currentTimeMillis() - lastRunTimeStart).append(" millis.\n"); + } + } + + benchRunTime = System.currentTimeMillis() - startupMillis - timeToShowMillis; + + final String message = "Java Version: " + System.getProperty("java.version") + "\n" + + "Time to Show: " + timeToShowMillis + " millis.\n" + + (runTimeSB != null ? runTimeSB.toString() : "") + + "Benchmark Run Time: " + benchRunTime + " millis.\n" + + "Average Run Time: " + (benchRunTime / benchRuns) + " millis (" + benchRuns + " runs).\n\n"; + + display.syncExec(new Runnable() { + public void run() { + if (benchOutFileName == null) { + MessageBox messageBox = new MessageBox(display.getActiveShell(), SWT.OK | SWT.ICON_INFORMATION); + messageBox.setText("Results"); + messageBox.setMessage(message); + messageBox.open(); + } else { + FileWriter fw = null; + try { + fw = new FileWriter(benchOutFileName, append); + fw.write(message); + } catch(IOException ex) { + ex.printStackTrace(); + } finally { + if (fw != null) + try {fw.close();} catch(IOException ex) {} + } + } + } + }); + + System.out.println(message); + + if (benchOutFileName != null) + System.exit(0); + } + }; + benchThread.start(); + } + + private void dispatchSelection() + { + int ix = pickerList.getSelectionIndex(); + if (ix == -1) + return; + + String methodName = "create" + panels[ix][0].replace(' ', '_'); + Control[] children = layoutDisplayPanel.getChildren(); + for (int i = 0; i < children.length; i++) + children[i].dispose(); + + try { + Control child = (Control) SwtDemo.class.getMethod(methodName, new Class[] {Composite.class}).invoke(SwtDemo.this, new Object[] {layoutDisplayPanel}); + child.setLayoutData("grow, wmin 500"); + descrTextArea.setText(panels[ix][1]); + layoutDisplayPanel.layout(); + } catch (Exception e1) { + e1.printStackTrace(); // Should never happpen... + } + } + + public Control createTest(Composite parent2) + { +// TabFolder tabFolder = new TabFolder(parent2, DOUBLE_BUFFER); + + Composite parent = new Composite(parent2, SWT.NONE); + + MigLayout layout = new MigLayout("wrap 2"); + layout.setColumnConstraints("[grow, shrink][grow, shrink]"); + parent.setLayout(layout); + + Label label = new Label(parent, SWT.WRAP); + label.setText("This is a long label"); + label.setLayoutData("width 20:pref:pref"); + + label = new Label(parent, SWT.NONE); + label.setText("Label 2"); + + label = new Label(parent, SWT.NONE); + label.setText("Label 3"); + + label = new Label(parent, SWT.NONE); + label.setText("Label 4"); + + return parent; + } + + public Control createWelcome(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + TabItem mainItem = createTabPanel(tabbedPane, "Welcome", new FillLayout()); + MigLayout lm = new MigLayout("ins 30, fill"); + Composite panel = createPanel(tabbedPane, lm); + mainItem.setControl(panel); + + String s = "MigLayout's main purpose is to make layouts for SWT and Swing, and possibly other frameworks, much more powerful and a lot easier to create, especially for manual coding.\n\n" + + "The motto is: \"MigLayout makes complex layouts easy and normal layouts one-liners.\"\n\n" + + "The layout engine is very flexible and advanced, something that is needed to make it simple to use yet handle almost all layout use-cases.\n\n" + + "MigLayout can handle all layouts that the commonly used Swing Layout Managers can handle and this with a lot of extra features. " + + "It also incorporates most, if not all, of the open source alternatives FormLayout's and TableLayout's functionality." + + "\n\n\nThanks to Karsten Lentzsch of JGoodies.com for allowing the reuse of the main demo application layout and for his inspiring talks that led to this layout Manager." + + "\n\n\nMikael Grev\n" + + "MiG InfoCom AB\n" + + "miglayout@miginfocom.com"; + + StyledText textArea = new StyledText(panel, SWT.MULTI | SWT.WRAP | SWT.BORDER); + textArea.setText(s); + textArea.setSize(400, 400); + textArea.setLayoutData("w 500:500,ay top,grow"); + deriveFont(textArea, SWT.BOLD, -1); + + return tabbedPane; + } + + public Composite createAPI_Constraints1(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + LC layC = new LC().fill().wrap(); + AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1); + AC rowC = new AC().align("top", 7).gap("15!", 6).grow(100, 8); + + TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout(layC, colC, rowC)); + + // References to text fields not stored to reduce code clutter. + + createList(p1, "Mouse, Mickey", new CC().dockWest().minWidth("150").gapX(null, "10")); + createLabel(p1, "Last Name", ""); + createTextField(p1, "", ""); + createLabel(p1, "First Name", ""); + createTextField(p1, "", new CC().wrap()); + createLabel(p1, "Phone", ""); + createTextField(p1, "", ""); + createLabel(p1, "Email", ""); + createTextField(p1, "", ""); + createLabel(p1, "Address 1", ""); + createTextField(p1, "", new CC().spanX().growX()); + createLabel(p1, "Address 2", ""); + createTextField(p1, "", new CC().spanX().growX()); + createLabel(p1, "City", ""); + createTextField(p1, "", new CC().wrap()); + createLabel(p1, "State", ""); + createTextField(p1, "", ""); + createLabel(p1, "Postal Code", ""); + createTextField(p1, "", new CC().spanX(2).growX(0)); + createLabel(p1, "Country", ""); + createTextField(p1, "", new CC().wrap()); + + createButton(p1, "New", new CC().spanX(5).split(5).tag("other")); + createButton(p1, "Delete", new CC().tag("other")); + createButton(p1, "Edit", new CC().tag("other")); + createButton(p1, "Save", new CC().tag("other")); + createButton(p1, "Cancel", new CC().tag("cancel")); + + return tabbedPane; + } + + public Composite createAPI_Constraints2(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + LC layC = new LC().fill().wrap(); + AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1); + AC rowC = new AC().index(6).gap("15!").align("top").grow(100, 8); + + TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout(layC, colC, rowC)); + + // References to text fields not stored to reduce code clutter. + + createLabel(p1, "Last Name", ""); + createTextField(p1, "", ""); + createLabel(p1, "First Name", ""); + createTextField(p1, "", new CC().wrap()); + createLabel(p1, "Phone", ""); + createTextField(p1, "", ""); + createLabel(p1, "Email", ""); + createTextField(p1, "", ""); + createLabel(p1, "Address 1", ""); + createTextField(p1, "", new CC().spanX().growX()); + createLabel(p1, "Address 2", ""); + createTextField(p1, "", new CC().spanX().growX()); + createLabel(p1, "City", ""); + createTextField(p1, "", new CC().wrap()); + createLabel(p1, "State", ""); + createTextField(p1, "", ""); + createLabel(p1, "Postal Code", ""); + createTextField(p1, "", new CC().spanX(2).growX(0)); + createLabel(p1, "Country", ""); + createTextField(p1, "", new CC().wrap()); + + createButton(p1, "New", new CC().spanX(5).split(5).tag("other")); + createButton(p1, "Delete", new CC().tag("other")); + createButton(p1, "Edit", new CC().tag("other")); + createButton(p1, "Save", new CC().tag("other")); + createButton(p1, "Cancel", new CC().tag("cancel")); + + return tabbedPane; + } + + public Composite createLayout_Showdown(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + TabItem p1 = createTabPanel(tabbedPane, "Layout Showdown (pure)", new MigLayout("", "[]15[][grow,fill]15[grow]")); + + // References to text fields not stored to reduce code clutter. + + createList(p1, "Mouse, Mickey", "spany, growy, wmin 150"); + createLabel(p1, "Last Name", ""); + createTextField(p1, "", ""); + createLabel(p1, "First Name", "split"); // split divides the cell + createTextField(p1, "", "growx, wrap"); + createLabel(p1, "Phone", ""); + createTextField(p1, "", ""); + createLabel(p1, "Email", "split"); + createTextField(p1, "", "growx, wrap"); + createLabel(p1, "Address 1", ""); + createTextField(p1, "", "span, growx"); // span merges cells + createLabel(p1, "Address 2", ""); + createTextField(p1, "", "span, growx"); + createLabel(p1, "City", ""); + createTextField(p1, "", "wrap"); // wrap continues on next line + createLabel(p1, "State", ""); + createTextField(p1, "", ""); + createLabel(p1, "Postal Code", "split"); + createTextField(p1, "", "growx, wrap"); + createLabel(p1, "Country", ""); + createTextField(p1, "", "wrap 15"); + + createButton(p1, "New", "span, split, align right"); + createButton(p1, "Delete", ""); + createButton(p1, "Edit", ""); + createButton(p1, "Save", ""); + createButton(p1, "Cancel", "wrap push"); + + + // Fixed version ******************************************* + + + TabItem p2 = createTabPanel(tabbedPane, "Layout Showdown (improved)", new MigLayout("", "[]15[][grow,fill]15[][grow,fill]")); + + // References to text fields not stored to reduce code clutter. + + createList(p2, "Mouse, Mickey", "spany, growy, wmin 150"); + createLabel(p2, "Last Name", ""); + createTextField(p2, "", ""); + createLabel(p2, "First Name", ""); + createTextField(p2, "", "wrap"); + createLabel(p2, "Phone", ""); + createTextField(p2, "", ""); + createLabel(p2, "Email", ""); + createTextField(p2, "", "wrap"); + createLabel(p2, "Address 1", ""); + createTextField(p2, "", "span"); + createLabel(p2, "Address 2", ""); + createTextField(p2, "", "span"); + createLabel(p2, "City", ""); + createTextField(p2, "", "wrap"); + createLabel(p2, "State", ""); + createTextField(p2, "", ""); + createLabel(p2, "Postal Code", ""); + createTextField(p2, "", "width 50, grow 0, wrap"); + createLabel(p2, "Country", ""); + createTextField(p2, "", "wrap 15"); + + createButton(p2, "New", "tag other, span, split"); + createButton(p2, "Delete", "tag other"); + createButton(p2, "Edit", "tag other"); + createButton(p2, "Save", "tag other"); + createButton(p2, "Cancel", "tag cancel, wrap push"); + + return tabbedPane; + } + + public Composite createDocking(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + tabbedPane.setLayoutData("grow"); + + TabItem p1 = createTabPanel(tabbedPane, "Docking 1", new MigLayout("fill")); + + createPanel(p1, "1. North", "north"); + createPanel(p1, "2. West", "west"); + createPanel(p1, "3. East", "east"); + createPanel(p1, "4. South", "south"); + + Table table = new Table(getComposite(p1), DOUBLE_BUFFER); + for (int i = 0; i < 6; i++) { + TableColumn tc = new TableColumn(table, SWT.LEFT | SWT.V_SCROLL | SWT.SCROLL_LINE); + tc.setText("Column " + (i + 1)); + tc.setWidth(100); + } + + for (int r = 0; r < 20; r++) { + TableItem item1 = new TableItem(table,0); + String[] data = new String[6]; + for (int c = 0; c < data.length; c++) + data[c] = "Cell " + (r + 1) + ", " + (c + 1); + item1.setText(data); + } + table.setHeaderVisible(true); + table.setLinesVisible(true); + table.setLayoutData("grow"); + + + TabItem p2 = createTabPanel(tabbedPane, "Docking 2 (fill)", new MigLayout("fill", "[c]", "")); + + createPanel(p2, "1. North", "north"); + createPanel(p2, "2. North", "north"); + createPanel(p2, "3. West", "west"); + createPanel(p2, "4. West", "west"); + createPanel(p2, "5. South", "south"); + createPanel(p2, "6. East", "east"); + createButton(p2, "7. Normal", ""); + createButton(p2, "8. Normal", ""); + createButton(p2, "9. Normal", ""); + + TabItem p3 = createTabPanel(tabbedPane, "Docking 3", new MigLayout()); + + createPanel(p3, "1. North", "north"); + createPanel(p3, "2. South", "south"); + createPanel(p3, "3. West", "west"); + createPanel(p3, "4. East", "east"); + createButton(p3, "5. Normal", ""); + + TabItem p4 = createTabPanel(tabbedPane, "Docking 4", new MigLayout()); + + createPanel(p4, "1. North", "north"); + createPanel(p4, "2. North", "north"); + createPanel(p4, "3. West", "west"); + createPanel(p4, "4. West", "west"); + createPanel(p4, "5. South", "south"); + createPanel(p4, "6. East", "east"); + createButton(p4, "7. Normal", ""); + createButton(p4, "8. Normal", ""); + createButton(p4, "9. Normal", ""); + + TabItem p5 = createTabPanel(tabbedPane, "Docking 5 (fillx)", new MigLayout("fillx", "[c]", "")); + + createPanel(p5, "1. North", "north"); + createPanel(p5, "2. North", "north"); + createPanel(p5, "3. West", "west"); + createPanel(p5, "4. West", "west"); + createPanel(p5, "5. South", "south"); + createPanel(p5, "6. East", "east"); + createButton(p5, "7. Normal", ""); + createButton(p5, "8. Normal", ""); + createButton(p5, "9. Normal", ""); + + TabItem p6 = createTabPanel(tabbedPane, "Random Docking", new MigLayout("fill")); + + String[] sides = {"north", "east", "south", "west"}; + Random rand = new Random(); + for (int i = 0; i < 20; i++) { + int side = rand.nextInt(4); + createPanel(p6, ((i + 1) + " " + sides[side]), sides[side]); + } + createPanel(p6, "I'm in the Center!", "grow"); + + return tabbedPane; + } + + public Control createAbsolute_Position(final Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // Pos tab + TabItem posTabPanel = createTabPanel(tabbedPane, "X Y Positions", new FillLayout()); + final Composite posPanel = createPanel(posTabPanel, new MigLayout()); + + createButton(posPanel, "pos 0.5al 0al", null); + createButton(posPanel, "pos 1al 0al", null); + createButton(posPanel, "pos 0.5al 0.5al", null); + createButton(posPanel, "pos 5in 45lp", null); + createButton(posPanel, "pos 0.5al 0.5al", null); + createButton(posPanel, "pos 0.5al 1al", null); + createButton(posPanel, "pos 1al .25al", null); + createButton(posPanel, "pos visual.x2-pref visual.y2-pref", null); + createButton(posPanel, "pos 1al -1in", null); + createButton(posPanel, "pos 100 100", null); + createButton(posPanel, "pos (10+(20*3lp)) 200", null); + createButton(posPanel, "Drag Window! (pos 500-container.xpos 500-container.ypos)", + "pos 500-container.xpos 500-container.ypos"); + + // Bounds tab + TabItem boundsTabPanel = createTabPanel(tabbedPane, "X1 Y1 X2 Y2 Bounds", new FillLayout()); + Composite boundsPanel = createPanel(boundsTabPanel, new MigLayout()); + + Label southLabel = createLabel(boundsPanel, "pos (visual.x+visual.w*0.1) visual.y2-40 (visual.x2-visual.w*0.1) visual.y2", null, SWT.CENTER | SWT.BORDER); + southLabel.setBackground(new Color(display, 200, 200, 255)); + deriveFont(southLabel, SWT.BOLD, 10); + + createButton(boundsPanel, "pos 0 0 container.x2 n", null); + createButton(boundsPanel, "pos visual.x 40 visual.x2 70", null); + createButton(boundsPanel, "pos visual.x 100 visual.x2 p", null); + createButton(boundsPanel, "pos 0.1al 0.4al n visual.y2-10", null); + createButton(boundsPanel, "pos 0.9al 0.4al n visual.y2-10", null); + createButton(boundsPanel, "pos 0.5al 0.5al, pad 3 0 -3 0", null); + createButton(boundsPanel, "pos n n 50% 50%", null); + createButton(boundsPanel, "pos 50% 50% n n", null); + createButton(boundsPanel, "pos 50% n n 50%", null); + createButton(boundsPanel, "pos n 50% 50% n", null); + + // Glass pane tab +// final TabItem glassPanel = createTabPanel(tabbedPane, "GlassPane Substitute", parent, new SwtMigLayout("align c c")); +// final Button butt = new Button("Press me!!"); +// glassPanel.add(butt); +// +// butt.addActionListener(new ActionListener() { +// public void actionPerformed(ActionEvent e) +// { +// butt.setEnabled(false); +// final JPanel bg = new JPanel(parent, new SwtMigLayout("align c c,fill")) { +// public void paint(Graphics g) +// { +// g.setColor(getBackground()); +// g.fillRect(0, 0, getWidth(), getHeight()); +// super.paint(g); +// } +// }; +// bg.setOpaque(false); +// configureActiveComponet(bg); +// +// final Label label = createLabel("You don't need a GlassPane to be cool!"); +// label.setFont(label.getFont().deriveFont(30f)); +// label.setForeground(new Color(255, 255, 255, 0)); +// bg.add(label, "align 50% 30%"); +// +// glassPanel.add(bg, "pos 0 0 visual.x2 visual.y2", 0); +// final long startTime = System.nanoTime(); +// final long endTime = startTime + 500000000L; +// +// glassPanel.revalidate(); +// +// final javax.swing.Timer timer = new Timer(25, null); +// +// timer.addActionListener(new ActionListener() { +// public void actionPerformed(ActionEvent e) +// { +// long now = System.nanoTime(); +// int alpha = (int) (((now - startTime) / (double) (endTime - startTime)) * 300); +// if (alpha < 150) +// bg.setBackground(new Color(100, 100, 100, alpha)); +// +// if (alpha > 150 && alpha < 405) { +// label.setForeground(new Color(255, 255, 255, (alpha - 150))); +// bg.repaint(); +// } +// if (alpha > 405) +// timer.stop(); +// } +// }); +// timer.start(); +// } +// }); +// + + parent.getShell().addControlListener(new ControlAdapter() { + public void controlMoved(ControlEvent e) + { + if (!posPanel.isDisposed()) { + posPanel.layout(); + } else { + parent.getShell().removeControlListener(this); + } + } + }); + + return tabbedPane; + } + + public Control createComponent_Links(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + TabItem linksPanel = createTabPanel(tabbedPane, "Component Links", new MigLayout()); + + // Links tab + createButton(linksPanel, "Mini", "pos null ta.y ta.x2 null, pad 3 0 -3 0"); + createTextArea(linksPanel, "Components, Please Link to Me!\nMy ID is: 'ta'", "id ta, pos 0.5al 0.5al, w 300"); + createButton(linksPanel, "id b1,pos ta.x2 ta.y2", null); + createButton(linksPanel, "pos b1.x2+rel b1.y visual.x2 null", null); + createCheck(linksPanel, "pos (ta.x+indent) (ta.y2+rel)", null); + createButton(linksPanel, "pos ta.x2+rel ta.y visual.x2 null", null); + createButton(linksPanel, "pos null ta.y+(ta.h-pref)/2 ta.x-rel null", null); + createButton(linksPanel, "pos ta.x ta.y2+100 ta.x2 null", null); + + // External tab + TabItem externalPanel = createTabPanel(tabbedPane, "External Components", new MigLayout()); + + Button extButt = createButton(externalPanel, "Bounds Externally Set!", "id ext, external"); + extButt.setBounds(250, 130, 200, 40); + createButton(externalPanel, "pos ext.x2 ext.y2", "pos ext.x2 ext.y2"); + createButton(externalPanel, "pos null null ext.x ext.y", "pos null null ext.x ext.y"); + + TabItem egTabPanel = createTabPanel(tabbedPane, "End Grouping", new FillLayout()); + final Composite egPanel = createPanel(egTabPanel, new MigLayout()); + + createButton(egPanel, "id b1, endgroupx g1, pos 200 200", null); + createButton(egPanel, "id b2, endgroupx g1, pos (b1.x+2ind) (b1.y2+rel)", null); + createButton(egPanel, "id b3, endgroupx g1, pos (b1.x+4ind) (b2.y2+rel)", null); + createButton(egPanel, "id b4, endgroupx g1, pos (b1.x+6ind) (b3.y2+rel)", null); + + // Group Bounds tab + TabItem gpTabPanel = createTabPanel(tabbedPane, "Group Bounds", new FillLayout()); + final Composite gpPanel = createPanel(gpTabPanel, new MigLayout()); + + createButton(gpPanel, "id grp1.b1, pos n 0.5al 50% n", null); + createButton(gpPanel, "id grp1.b2, pos 50% 0.5al n n", null); + createButton(gpPanel, "id grp1.b3, pos 0.5al n n b1.y", null); + createButton(gpPanel, "id grp1.b4, pos 0.5al b1.y2 n n", null); + + createButton(gpPanel, "pos n grp1.y2 grp1.x n", null); + createButton(gpPanel, "pos n n grp1.x grp1.y", null); + createButton(gpPanel, "pos grp1.x2 n n grp1.y", null); + createButton(gpPanel, "pos grp1.x2 grp1.y2", null); + + Composite boundsPanel = createPanel(gpPanel, (Layout) null); + boundsPanel.setLayoutData("pos grp1.x grp1.y grp1.x2 grp1.y2"); + boundsPanel.setBackground(new Color(display, 200, 200, 255)); + + return tabbedPane; + } + + public Control createFlow_Direction(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + createFlowPanel(tabbedPane, "Layout: flowx, Cell: flowx", "", "flowx"); + createFlowPanel(tabbedPane, "Layout: flowx, Cell: flowy", "", "flowy"); + createFlowPanel(tabbedPane, "Layout: flowy, Cell: flowx", "flowy", "flowx"); + createFlowPanel(tabbedPane, "Layout: flowy, Cell: flowy", "flowy", "flowy"); + + return tabbedPane; + } + + private TabItem createFlowPanel(TabFolder parent, String text, String gridFlow, String cellFlow) + { + MigLayout lm = new MigLayout("center, wrap 3," + gridFlow, + "[110,fill]", + "[110,fill]"); + TabItem panel = createTabPanel(parent, text, lm); + + for (int i = 0; i < 9; i++) { + Composite b = createPanel(panel, "" + (i + 1), cellFlow); + Font f = deriveFont(b, SWT.DEFAULT, 20); + b.getChildren()[0].setFont(f); + } + + Composite b = createPanel(panel, "5:2", cellFlow + ",cell 1 1"); + Font f = deriveFont(b, SWT.DEFAULT, 20); + b.getChildren()[0].setFont(f); + + return panel; + } + + public Control createDebug(Composite parent) + { + return createPlainImpl(parent, true); + } + + public Control createButton_Bars(final Composite parent) + { + MigLayout lm = new MigLayout("ins 0 0 15lp 0", + "[grow]", + "[grow]u[baseline,nogrid]"); + + final Composite mainPanel = new Composite(parent, DOUBLE_BUFFER); + mainPanel.setLayout(lm); + + TabFolder tabbedPane = new TabFolder(mainPanel, DOUBLE_BUFFER); + tabbedPane.setLayoutData("grow, wrap"); + + createButtonBarsPanel(tabbedPane, "Buttons", "help", false); + createButtonBarsPanel(tabbedPane, "Buttons with Help2", "help2", false); + createButtonBarsPanel(tabbedPane, "Buttons (Same width)", "help", true); + + createLabel(mainPanel, "Button Order:", ""); + final Label formatLabel = createLabel(mainPanel, "", "growx"); + deriveFont(formatLabel, SWT.BOLD , -1); + + final Button winButt = createToggleButton(mainPanel, "Windows", "wmin button"); + final Button macButt = createToggleButton(mainPanel, "Mac OS X", "wmin button"); + + winButt.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) + { + if (winButt.getSelection()) { + PlatformDefaults.setPlatform(PlatformDefaults.WINDOWS_XP); + formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'"); + macButt.setSelection(false); + mainPanel.layout(); + } + } + }); + + macButt.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) + { + if (macButt.getSelection()) { + PlatformDefaults.setPlatform(PlatformDefaults.MAC_OSX); + formatLabel.setText("'" + PlatformDefaults.getButtonOrder() + "'"); + winButt.setSelection(false); + mainPanel.layout(); + } + } + }); + + Button helpButt = createButton(mainPanel, "Help", "gap unrel,wmin button"); + helpButt.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) + { + MessageBox msgBox = new MessageBox(parent.getShell()); + msgBox.setMessage("See JavaDoc for PlatformConverter.getButtonBarOrder(..) for details on the format string."); + msgBox.open(); + } + }); + + (PlatformDefaults.getPlatform() == PlatformDefaults.WINDOWS_XP ? winButt : macButt).setSelection(true); + + return mainPanel; + } + + private TabItem createButtonBarsPanel(TabFolder parent, String text, String helpTag, boolean sizeLocked) + { + MigLayout lm = new MigLayout("nogrid, fillx, aligny 100%, gapy unrel"); + TabItem panel = createTabPanel(parent, text, lm); + + // Notice that the order in the rows below does not matter... + String[][] buttons = new String[][] { + {"No", "Yes"}, + {"Help", "Close"}, + {"OK", "Help"}, + {"OK", "Cancel", "Help"}, + {"OK", "Cancel", "Apply", "Help"}, + {"No", "Yes", "Cancel"}, + {"Help", "< Move Back", "Move Forward >", "Cancel"}, + {"Print...", "Cancel", "Help"}, + }; + + for (int r = 0; r < buttons.length; r++) { + for (int i = 0; i < buttons[r].length; i++) { + String txt = buttons[r][i]; + String tag = txt; + + if (txt.equals("Help")) { + tag = helpTag; + } else if (txt.equals("< Move Back")) { + tag = "back"; + } else if (txt.equals("Close")) { + tag = "cancel"; + } else if (txt.equals("Move Forward >")) { + tag = "next"; + } else if (txt.equals("Print...")) { + tag = "other"; + } + String wrap = (i == buttons[r].length - 1) ? ",wrap" : ""; + String sizeGroup = sizeLocked ? ("sgx " + r + ",") : ""; + createButton(panel, txt, sizeGroup + "tag " + tag + wrap); + } + } + + return panel; + } + + public Control createOrientation(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + MigLayout lm = new MigLayout("flowy", "[grow,fill]", "[]0[]15lp[]0[]"); + TabItem mainPanel = createTabPanel(tabbedPane, "Orientation", lm); + + // Default orientation + MigLayout defLM = new MigLayout("", "[][grow,fill]", ""); + + Composite defPanel = createPanel(mainPanel, defLM); + addSeparator(defPanel, "Default Orientation"); + createLabel(defPanel, "Level", ""); + createTextField(defPanel, "", "span,growx"); + createLabel(defPanel, "Radar", ""); + createTextField(defPanel, "", ""); + createTextField(defPanel, "", ""); + + // Right-to-left, Top-to-bottom + MigLayout rtlLM = new MigLayout("rtl,ttb", + "[][grow,fill]", + ""); + Composite rtlPanel = createPanel(mainPanel, rtlLM); + addSeparator(rtlPanel, "Right to Left"); + createLabel(rtlPanel, "Level", ""); + createTextField(rtlPanel, "", "span,growx"); + createLabel(rtlPanel, "Radar", ""); + createTextField(rtlPanel, "", ""); + createTextField(rtlPanel, "", ""); + + // Right-to-left, Bottom-to-top + MigLayout rtlbLM = new MigLayout("rtl,btt", + "[][grow,fill]", + ""); + Composite rtlbPanel = createPanel(mainPanel, rtlbLM); + addSeparator(rtlbPanel, "Right to Left, Bottom to Top"); + createLabel(rtlbPanel, "Level", ""); + createTextField(rtlbPanel, "", "span,growx"); + createLabel(rtlbPanel, "Radar", ""); + createTextField(rtlbPanel, "", ""); + createTextField(rtlbPanel, "", ""); + + // Left-to-right, Bottom-to-top + MigLayout ltrbLM = new MigLayout("ltr,btt", + "[][grow,fill]", + ""); + + Composite ltrbPanel = createPanel(mainPanel, ltrbLM); + addSeparator(ltrbPanel, "Left to Right, Bottom to Top"); + createLabel(ltrbPanel, "Level", ""); + createTextField(ltrbPanel, "", "span,growx"); + createLabel(ltrbPanel, "Radar", ""); + createTextField(ltrbPanel, "", ""); + createTextField(ltrbPanel, "", ""); + + return tabbedPane; + } + + public Control createCell_Position(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // Absolute grid position + MigLayout absLM = new MigLayout("", + "[100:pref,fill]", + "[100:pref,fill]"); + + TabItem absPanel = createTabPanel(tabbedPane, "Absolute", absLM); + createPanel(absPanel, "cell 0 0", null); + createPanel(absPanel, "cell 2 0", null); + createPanel(absPanel, "cell 3 0", null); + createPanel(absPanel, "cell 1 1", null); + createPanel(absPanel, "cell 0 2", null); + createPanel(absPanel, "cell 2 2", null); + createPanel(absPanel, "cell 2 2", null); + + + // Relative grid position with wrap + MigLayout relAwLM = new MigLayout("wrap", + "[100:pref,fill][100:pref,fill][100:pref,fill][100:pref,fill]", + "[100:pref,fill]"); + TabItem relAwPanel = createTabPanel(tabbedPane, "Relative + Wrap", relAwLM); + createPanel(relAwPanel, "", null); + createPanel(relAwPanel, "skip", null); + createPanel(relAwPanel, "", null); + createPanel(relAwPanel, "skip,wrap", null); + createPanel(relAwPanel, "", null); + createPanel(relAwPanel, "skip,split", null); + createPanel(relAwPanel, "", null); + + + // Relative grid position with manual wrap + MigLayout relWLM = new MigLayout("", + "[100:pref,fill]", + "[100:pref,fill]"); + TabItem relWPanel = createTabPanel(tabbedPane, "Relative", relWLM); + createPanel(relWPanel, "", null); + createPanel(relWPanel, "skip", null); + createPanel(relWPanel, "wrap", null); + createPanel(relWPanel, "skip,wrap", null); + createPanel(relWPanel, "", null); + createPanel(relWPanel, "skip,split", null); + createPanel(relWPanel, "", null); + + + // Mixed relative and absolute grid position + MigLayout mixLM = new MigLayout("", + "[100:pref,fill]", + "[100:pref,fill]"); + TabItem mixPanel = createTabPanel(tabbedPane, "Mixed", mixLM); + createPanel(mixPanel, "", null); + createPanel(mixPanel, "cell 2 0", null); + createPanel(mixPanel, "", null); + createPanel(mixPanel, "cell 1 1,wrap", null); + createPanel(mixPanel, "", null); + createPanel(mixPanel, "cell 2 2,split", null); + createPanel(mixPanel, "", null); + + return tabbedPane; + } + + public Control createPlain(Composite parent) + { + return createPlainImpl(parent, false); + } + + private Control createPlainImpl(Composite parent, boolean debug) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + MigLayout lm = new MigLayout((debug && benchRuns == 0 ? "debug" : ""), "[r][100lp, fill][60lp][95lp, fill]", ""); + TabItem panel = createTabPanel(tabbedPane, "Plain", lm); + + addSeparator(panel, "Manufacturer"); + createLabel(panel, "Company", ""); + createTextField(panel, "", "span,growx"); + createLabel(panel, "Contact", ""); + createTextField(panel, "", "span,growx"); + createLabel(panel, "Order No", ""); + createTextField(panel, "", "wmin 15*6,wrap"); + + addSeparator(panel, "Inspector"); + createLabel(panel, "Name", ""); + createTextField(panel, "", "span,growx"); + createLabel(panel, "Reference No", ""); + createTextField(panel, "", "wrap"); + createLabel(panel, "Status", ""); + createCombo(panel, new String[] {"In Progress", "Finnished", "Released"}, "wrap"); + + addSeparator(panel, "Ship"); + createLabel(panel, "Shipyard", ""); + createTextField(panel, "", "span,growx"); + createLabel(panel, "Register No", ""); + createTextField(panel, "", ""); + createLabel(panel, "Hull No", "right"); + createTextField(panel, "", "wmin 15*6,wrap"); + createLabel(panel, "Project Type", ""); + createCombo(panel, new String[] {"New Building", "Convention", "Repair"}, "wrap"); + + if (debug) + createLabel(panel, "Blue is component bounds. Cell bounds (red) can not be shown in SWT", "newline,ax left,span,gaptop 40"); + + return tabbedPane; + } + + public Control createBound_Sizes(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + for (int i = 0; i < 2; i++) { // Jumping for 0 and Stable for 1 + String colConstr = i == 0 ? "[right][200]" : "[right, 75lp:pref][200]"; + + MigLayout LM1 = new MigLayout("wrap", colConstr, ""); + TabItem panel1 = createTabPanel(tabbedPane, i == 0 ? "Jumping 1" : "Stable 2", LM1); + createLabel(panel1, "File Number:", ""); + createTextField(panel1, "", "growx"); + createLabel(panel1, "RFQ Number:", ""); + createTextField(panel1, "", "growx"); + createLabel(panel1, "Entry Date:", ""); + createTextField(panel1, "", "wmin 6*6"); + createLabel(panel1, "Sales Person:", ""); + createTextField(panel1, "", "growx"); + + MigLayout LM2 = new MigLayout("wrap", colConstr, ""); + TabItem panel2 = createTabPanel(tabbedPane, i == 0 ? "Jumping 2" : "Stable 2", LM2); + createLabel(panel2, "Shipper:", ""); + createTextField(panel2, "", "wmin 6*6,split 2"); + createTextField(panel2, "", "growx"); + createLabel(panel2, "Consignee:", ""); + createTextField(panel2, "", "wmin 6*6,split 2"); + createTextField(panel2, "", "growx"); + createLabel(panel2, "Departure:", ""); + createTextField(panel2, "", "wmin 6*6,split 2"); + createTextField(panel2, "", "growx"); + createLabel(panel2, "Destination:", ""); + createTextField(panel2, "", "wmin 6*6,split 2"); + createTextField(panel2, "", "growx"); + } + return tabbedPane; + } + + public Control createComponent_Sizes(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + MigLayout lm = new MigLayout("wrap", "[right][0:pref,grow]", ""); + + TabItem tabPanel = createTabPanel(tabbedPane, "Component Sizes", new FillLayout()); + + SashForm sashForm = new SashForm(getComposite(tabPanel), SWT.HORIZONTAL | SWT.SMOOTH); + sashForm.setBackground(new Color(display, 50, 50, 50)); + + Composite panel = createPanel(sashForm, lm); + createTextArea(sashForm, "Use slider to see how the components grow and shrink depending on the constraints set on them.", ""); + + createLabel(panel, "", ""); + createTextField(panel, "8 ", ""); + createLabel(panel, "width min!", null); + createTextField(panel, "3 ", "width min!"); + createLabel(panel, "width pref!", ""); + createTextField(panel, "3 ", "width pref!"); + createLabel(panel, "width min:pref", null); + createTextField(panel, "8 ", "width min:pref"); + createLabel(panel, "width min:100:150", null); + createTextField(panel, "8 ", "width min:100:150"); + createLabel(panel, "width min:100:150, growx", null); + createTextField(panel, "8 ", "width min:100:150, growx"); + createLabel(panel, "width min:100, growx", null); + createTextField(panel, "8 ", "width min:100, growx"); + createLabel(panel, "width 40!", null); + createTextField(panel, "8 ", "width 40!"); + createLabel(panel, "width 40:40:40", null); + createTextField(panel, "8 ", "width 40:40:40"); + + return tabbedPane; + } + + public Control createCell_Alignments(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // Horizontal + MigLayout hLM = new MigLayout("wrap", + "[grow,left][grow,center][grow,right][grow,fill,center]", + "[]unrel[][]"); + TabItem hPanel = createTabPanel(tabbedPane, "Horizontal", hLM); + String[] sizes = new String[] {"", "growx", "growx 0", "left", "center", "right", "leading", "trailing"}; + createLabel(hPanel, "[left]", "c"); + createLabel(hPanel, "[center]", "c"); + createLabel(hPanel, "[right]", "c"); + createLabel(hPanel, "[fill,center]", "c, growx 0"); + + for (int r = 0; r < sizes.length; r++) { + for (int c = 0; c < 4; c++) { + String text = sizes[r].length() > 0 ? sizes[r] : "default"; + createButton(hPanel, text, sizes[r]); + } + } + + // Vertical + MigLayout vLM = new MigLayout("wrap,flowy", + "[right][]", + "[grow,top][grow,center][grow,bottom][grow,fill,bottom][grow,fill,baseline]"); + TabItem vPanel = createTabPanel(tabbedPane, "Vertical", vLM); + String[] vSizes = new String[] {"", "growy", "growy 0", "top", "center", "bottom"}; + createLabel(vPanel, "[top]", "center"); + createLabel(vPanel, "[center]", "center"); + createLabel(vPanel, "[bottom]", "center"); + createLabel(vPanel, "[fill, bottom]", "center, growy 0"); + createLabel(vPanel, "[fill, baseline]", "center"); + + for (int c = 0; c < vSizes.length; c++) { + for (int r = 0; r < 5; r++) { + String text = vSizes[c].length() > 0 ? vSizes[c] : "default"; + createButton(vPanel, text, vSizes[c]); + } + } + + return tabbedPane; + } + + public Control createUnits(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // Horizontal + MigLayout hLM = new MigLayout("wrap", + "[right][]", + ""); + TabItem hPanel = createTabPanel(tabbedPane, "Horizontal", hLM); + String[] sizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "30sp"}; + for (int i = 0; i < sizes.length; i++) { + createLabel(hPanel, sizes[i], ""); + createTextField(hPanel, "", "width " + sizes[i] + ""); + } + + // Horizontal lp + MigLayout hlpLM = new MigLayout("", "[right][][]", ""); + TabItem hlpPanel = createTabPanel(tabbedPane, "Horizontal LP", hlpLM); + createLabel(hlpPanel, "9 cols", ""); + createTextField(hlpPanel, "", "wmin 9*6"); + String[] lpSizes = new String[] {"75lp", "75px", "88px", "100px"}; + createLabel(hlpPanel, "", "wrap"); + for (int i = 0; i < lpSizes.length; i++) { + createLabel(hlpPanel, lpSizes[i], ""); + createTextField(hlpPanel, "", "width " + lpSizes[i] + ", wrap"); + } + + // Vertical + MigLayout vLM = new MigLayout("wrap,flowy", + "[c]", + "[top][top]"); + TabItem vPanel = createTabPanel(tabbedPane, "Vertical", vLM); + String[] vSizes = new String[] {"72pt", "25.4mm", "2.54cm", "1in", "72px", "96px", "120px", "25%", "30sp"}; + for (int i = 0; i < sizes.length; i++) { + createLabel(vPanel, vSizes[i], ""); + createTextArea(vPanel, "", "width 50!, height " + vSizes[i] + ""); + } + + // Vertical lp + MigLayout vlpLM = new MigLayout("wrap,flowy", + "[c]", + "[top][top]40px[top][top]"); + TabItem vlpPanel = createTabPanel(tabbedPane, "Vertical LP", vlpLM); + createLabel(vlpPanel, "4 rows", ""); + createTextArea(vlpPanel, "\n\n\n\n", "width 50!"); + createLabel(vlpPanel, "field", ""); + createTextField(vlpPanel, "", "wmin 5*9"); + + String[] vlpSizes1 = new String[] {"63lp", "57px", "63px", "68px", "25%"}; + String[] vlpSizes2 = new String[] {"21lp", "21px", "23px", "24px", "10%"}; + for (int i = 0; i < vlpSizes1.length; i++) { + createLabel(vlpPanel, vlpSizes1[i], ""); + createTextArea(vlpPanel, "", "width 50!, height " + vlpSizes1[i] + ""); + createLabel(vlpPanel, vlpSizes2[i], ""); + createTextField(vlpPanel, "", "height " + vlpSizes2[i] + "!,wmin 5*6"); + } + + createLabel(vlpPanel, "button", "skip 2"); + createButton(vlpPanel, "...", ""); + + return tabbedPane; + } + + public Control createGrouping(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // Ungrouped + MigLayout ugM = new MigLayout("", "[]push[][][]", ""); + TabItem ugPanel = createTabPanel(tabbedPane, "Ungrouped", ugM); + createButton(ugPanel, "Help", ""); + createButton(ugPanel, "< Back", "gap push"); + createButton(ugPanel, "Forward >", ""); + createButton(ugPanel, "Apply", "gap unrel"); + createButton(ugPanel, "Cancel", "gap unrel"); + + // Grouped Components + MigLayout gM = new MigLayout("nogrid, fillx"); + TabItem gPanel = createTabPanel(tabbedPane, "Grouped (Components)", gM); + createButton(gPanel, "Help", "sg"); + createButton(gPanel, "< Back", "sg, gap push"); + createButton(gPanel, "Forward >", "sg"); + createButton(gPanel, "Apply", "sg, gap unrel"); + createButton(gPanel, "Cancel", "sg, gap unrel"); + + // Grouped Columns + MigLayout gcM = new MigLayout("", "[sg,fill]push[sg,fill][sg,fill]unrel[sg,fill]unrel[sg,fill]", ""); + TabItem gcPanel = createTabPanel(tabbedPane, "Grouped (Columns)", gcM); + createButton(gcPanel, "Help", ""); + createButton(gcPanel, "< Back", ""); + createButton(gcPanel, "Forward >", ""); + createButton(gcPanel, "Apply", ""); + createButton(gcPanel, "Cancel", ""); + + // Ungrouped Rows + MigLayout ugrM = new MigLayout(); // no "sg" is the only difference to next panel + TabItem ugrPanel = createTabPanel(tabbedPane, "Ungrouped Rows", ugrM); + createLabel(ugrPanel, "File Number:", ""); + createTextField(ugrPanel, "30 ", "wrap"); + createLabel(ugrPanel, "BL/MBL number:", ""); + createTextField(ugrPanel, "7 ", "split 2"); + createTextField(ugrPanel, "7 ", "wrap"); + createLabel(ugrPanel, "Entry Date:", ""); + createTextField(ugrPanel, "7 ", "wrap"); + createLabel(ugrPanel, "RFQ Number:", ""); + createTextField(ugrPanel, "30 ", "wrap"); + createLabel(ugrPanel, "Goods:", ""); + createCheck(ugrPanel, "Dangerous", "wrap"); + createLabel(ugrPanel, "Shipper:", ""); + createTextField(ugrPanel, "30 ", "wrap"); + createLabel(ugrPanel, "Customer:", ""); + createTextField(ugrPanel, "", "split 2,growx"); + createButton(ugrPanel, "...", "width 60px:pref,wrap"); + createLabel(ugrPanel, "Port of Loading:", ""); + createTextField(ugrPanel, "30 ", "wrap"); + createLabel(ugrPanel, "Destination:", ""); + createTextField(ugrPanel, "30 ", "wrap"); + + // Grouped Rows + MigLayout grM = new MigLayout("", "[]", "[sg]"); // "sg" is the only difference to previous panel + TabItem grPanel = createTabPanel(tabbedPane, "Grouped Rows", grM); + createLabel(grPanel, "File Number:", ""); + createTextField(grPanel, "30 ","wrap"); + createLabel(grPanel, "BL/MBL number:", ""); + createTextField(grPanel, "7 ","split 2"); + createTextField(grPanel, "7 ", "wrap"); + createLabel(grPanel, "Entry Date:", ""); + createTextField(grPanel, "7 ", "wrap"); + createLabel(grPanel, "RFQ Number:", ""); + createTextField(grPanel, "30 ", "wrap"); + createLabel(grPanel, "Goods:", ""); + createCheck(grPanel, "Dangerous", "wrap"); + createLabel(grPanel, "Shipper:", ""); + createTextField(grPanel, "30 ", "wrap"); + createLabel(grPanel, "Customer:", ""); + createTextField(grPanel, "", "split 2,growx"); + createButton(grPanel, "...", "width 50px:pref,wrap"); + createLabel(grPanel, "Port of Loading:", ""); + createTextField(grPanel, "30 ", "wrap"); + createLabel(grPanel, "Destination:", ""); + createTextField(grPanel, "30 ", "wrap"); + + return tabbedPane; + } + + public Control createSpan(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // Horizontal span + MigLayout colLM = new MigLayout("", + "[fill][25%,fill][105lp!,fill][150px!,fill]", + "[]15[][]"); + TabItem colPanel = createTabPanel(tabbedPane, "Column Span/Split", colLM); + createTextField(colPanel, "Col1 [ ]", ""); + createTextField(colPanel, "Col2 [25%]", ""); + createTextField(colPanel, "Col3 [105lp!]", ""); + createTextField(colPanel, "Col4 [150px!]", "wrap"); + + createLabel(colPanel, "Full Name:", ""); + createTextField(colPanel, "span, growx ", "span,growx"); + + createLabel(colPanel, "Phone:", ""); + createTextField(colPanel, " ", "span 3, split 5"); + createTextField(colPanel, " ", null); + createTextField(colPanel, " ", null); + createTextField(colPanel, " ", null); + createLabel(colPanel, "(span 3, split 4)", "wrap"); + + createLabel(colPanel, "Zip/City:", ""); + createTextField(colPanel, " ", ""); + createTextField(colPanel, "span 2, growx", null); + + // Vertical span + MigLayout rowLM = new MigLayout("wrap", + "[225lp]para[225lp]", + "[]3[]unrel[]3[]unrel[]3[]"); + TabItem rowPanel = createTabPanel(tabbedPane, "Row Span", rowLM); + createLabel(rowPanel, "Name", ""); + createLabel(rowPanel, "Notes", ""); + createTextField(rowPanel, "growx", null); + createTextArea(rowPanel, "spany,grow ", "spany,grow,hmin 13*5"); + createLabel(rowPanel, "Phone", ""); + createTextField(rowPanel, "growx", null); + createLabel(rowPanel, "Fax", ""); + createTextField(rowPanel, "growx", null); + + + return tabbedPane; + } + + public Control createGrowing(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // All tab + MigLayout allLM = new MigLayout("", + "[pref!][grow,fill]", + "[]15[]"); + TabItem allTab = createTabPanel(tabbedPane, "All", allLM); + createLabel(allTab, "Fixed", ""); + createLabel(allTab, "Gets all extra space", "wrap"); + createTextField(allTab, " ", ""); + createTextField(allTab, " ", ""); + + // Half tab + MigLayout halfLM = new MigLayout("", + "[pref!][grow,fill]", + "[]15[]"); + TabItem halfTab = createTabPanel(tabbedPane, "Half", halfLM); + createLabel(halfTab, "Fixed", ""); + createLabel(halfTab, "Gets half of extra space", ""); + createLabel(halfTab, "Gets half of extra space", "wrap"); + createTextField(halfTab, " ", ""); + createTextField(halfTab, " ", ""); + createTextField(halfTab, " ", ""); + + // Percent 1 tab + MigLayout p1LM = new MigLayout("", + "[pref!][0:0,grow 25,fill][0:0,grow 75,fill]", + "[]15[]"); + TabItem p1Tab = createTabPanel(tabbedPane, "Percent 1", p1LM); + createLabel(p1Tab, "Fixed", ""); + createLabel(p1Tab, "Gets 25% of extra space", ""); + createLabel(p1Tab, "Gets 75% of extra space", "wrap"); + createTextField(p1Tab, " ", ""); + createTextField(p1Tab, " ", ""); + createTextField(p1Tab, " ", ""); + + // Percent 2 tab + MigLayout p2LM = new MigLayout("", + "[0:0,grow 33,fill][0:0,grow 67,fill]", + "[]15[]"); + TabItem p2Tab = createTabPanel(tabbedPane, "Percent 2", p2LM); + createLabel(p2Tab, "Gets 33% of extra space", ""); + createLabel(p2Tab, "Gets 67% of extra space", "wrap"); + createTextField(p2Tab, " ", ""); + createTextField(p2Tab, " ", ""); + + // Vertical 1 tab + MigLayout v1LM = new MigLayout("flowy", + "[]15[]", + "[][c,pref!][c,grow 25,fill][c,grow 75,fill]"); + TabItem v1Tab = createTabPanel(tabbedPane, "Vertical 1", v1LM); + createLabel(v1Tab, "Fixed", "skip"); + createLabel(v1Tab, "Gets 25% of extra space", ""); + createLabel(v1Tab, "Gets 75% of extra space", "wrap"); + createLabel(v1Tab, "new Text(SWT.MULTI | SWT.WRAP | SWT.BORDER)", ""); + createTextArea(v1Tab, "", "hmin 4*13"); + createTextArea(v1Tab, "", "hmin 4*13"); + createTextArea(v1Tab, "", "hmin 4*13"); + + // Vertical 2 tab + MigLayout v2LM = new MigLayout("flowy", + "[]15[]", + "[][c,grow 33,fill][c,grow 67,fill]"); + TabItem v2Tab = createTabPanel(tabbedPane, "Vertical 2", v2LM); + createLabel(v2Tab, "Gets 33% of extra space", "skip"); + createLabel(v2Tab, "Gets 67% of extra space", "wrap"); + createLabel(v2Tab, "new Text(SWT.MULTI | SWT.WRAP | SWT.BORDER)", ""); + createTextArea(v2Tab, "", "hmin 4*13"); + createTextArea(v2Tab, "", "hmin 4*13"); + + return tabbedPane; + } + + public Control createBasic_Sizes(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // Horizontal tab + MigLayout horLM = new MigLayout("", + "[]15[75px]25[min]25[]", + "[]15"); + TabItem horTab = createTabPanel(tabbedPane, "Horizontal - Column size set", horLM); + createLabel(horTab, "75px", "skip"); + createLabel(horTab, "Min", ""); + createLabel(horTab, "Pref", "wrap"); + + createLabel(horTab, "new Text(15)", ""); + createTextField(horTab, "", "wmin 10"); + createTextField(horTab, "", "wmin 10"); + createTextField(horTab, "", "wmin 10"); + + // Vertical tab 1 + MigLayout verLM = new MigLayout("flowy,wrap", + "[]15[]", + "[]15[c,45:45]15[c,min]15[c,pref]"); + TabItem verTab = createTabPanel(tabbedPane, "\"Vertical - Row sized\"", verLM); + createLabel(verTab, "45px", "skip"); + createLabel(verTab, "Min", ""); + createLabel(verTab, "Pref", ""); + + createLabel(verTab, "new Text(SWT.MULTI)", ""); + createTextArea(verTab, "", ""); + createTextArea(verTab, "", ""); + createTextArea(verTab, "", ""); + + // Componentsized/Baseline 2 + MigLayout verLM2 = new MigLayout("flowy,wrap", + "[]15[]", + "[]15[baseline]15[baseline]15[baseline]"); + TabItem verTab2 = createTabPanel(tabbedPane, "\"Vertical - Component sized + Baseline\"", verLM2); + createLabel(verTab2, "45px", "skip"); + createLabel(verTab2, "Min", ""); + createLabel(verTab2, "Pref", ""); + + createLabel(verTab2, "new Text(SWT.MULTI)", ""); + createTextArea(verTab2, "", "height 45"); + createTextArea(verTab2, "", "height min"); + createTextArea(verTab2, "", "height pref"); + + return tabbedPane; + } + + public Control createAlignments(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // Horizontal tab + MigLayout horLM = new MigLayout("wrap", + "[label]15[left]15[center]15[right]15[fill]15[]", + "[]15[]"); + + String[] horLabels = new String[] {"[label]", "[left]", "[center]", "[right]", "[fill]", "[] (Default)"}; + TabItem horTab = createTabPanel(tabbedPane, "Horizontal", horLM); + String[] horNames = new String[] {"First Name", "Phone Number", "Facsmile", "Email", "Address", "Other"}; + for (int c = 0; c < horLabels.length; c++) + createLabel(horTab, horLabels[c], ""); + + for (int r = 0; r < horLabels.length; r++) { + for (int c = 0; c < horNames.length; c++) { + if (c == 0) { + createLabel(horTab, horNames[r] + ":", ""); + } else { + createButton(horTab, horNames[r], ""); + } + } + } + + // Vertical tab + MigLayout verLM = new MigLayout("wrap,flowy", + "[]unrel[]rel[]", + "[top]15[center]15[bottom]15[fill]15[fill,baseline]15[baseline]15[]"); + + String[] verLabels = new String[] {"[top]", "[center]", "[bottom]", "[fill]", "[fill,baseline]", "[baseline]", "[] (Default)"}; + TabItem verTab = createTabPanel(tabbedPane, "Vertical", verLM); + + for (int c = 0; c < verLabels.length; c++) + createLabel(verTab, verLabels[c], ""); + + for (int c = 0; c < verLabels.length; c++) + createButton(verTab, "A Button", ""); + + for (int c = 0; c < verLabels.length; c++) + createTextField(verTab, "JTextFied", ""); + + for (int c = 0; c < verLabels.length; c++) + createTextArea(verTab, "Text ", ""); + + for (int c = 0; c < verLabels.length; c++) + createTextArea(verTab, "Text\nwith two lines", ""); + + for (int c = 0; c < verLabels.length; c++) + createTextArea(verTab, "Scrolling Text\nwith two lines", ""); + + return tabbedPane; + } + + public Control createQuick_Start(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + MigLayout lm = new MigLayout("wrap", + "[right][fill,sizegroup]unrel[right][fill,sizegroup]", + ""); + + TabItem p = createTabPanel(tabbedPane, "Quick Start", lm); + + addSeparator(p, "General"); + createLabel(p, "Company", "gap indent"); + createTextField(p, "", "span,growx"); + createLabel(p, "Contact", "gap indent"); + createTextField(p, "", "span,growx"); + + addSeparator(p, "Propeller"); + createLabel(p, "PTI/kW", "gap indent"); + createTextField(p, "", "wmin 100"); + createLabel(p, "Power/kW", "gap indent"); + createTextField(p, "", "wmin 100"); + createLabel(p, "R/mm", "gap indent"); + createTextField(p, "", "wmin 100"); + createLabel(p, "D/mm", "gap indent"); + createTextField(p, "", "wmin 100"); + + return tabbedPane; + } + + public Control createGrow_Shrink(Composite parent) + { + TabFolder tabbedPane = new TabFolder(parent, DOUBLE_BUFFER); + + // shrink tab + MigLayout slm = new MigLayout("nogrid"); + TabItem shrinkTabPanel = createTabPanel(tabbedPane, "Shrink", new FillLayout()); + + + SashForm shrinkSash = new SashForm(getComposite(shrinkTabPanel), SWT.HORIZONTAL | SWT.SMOOTH); + shrinkSash.setBackground(new Color(display, 100, 100, 100)); + + Composite shrinkPanel = createPanel(shrinkSash, slm); + shrinkPanel.setLayoutData("wmin 100"); + + createTextField(shrinkPanel, "shp 110", "shp 110,w 10:130"); + createTextField(shrinkPanel, "Default (100)", "w 10:130"); + createTextField(shrinkPanel, "shp 90", "shp 90,w 10:130"); + + createTextField(shrinkPanel, "shrink 25", "newline,shrink 25,w 10:130"); + createTextField(shrinkPanel, "shrink 75", "shrink 75,w 10:130"); + + createTextField(shrinkPanel, "Default", "newline, w 10:130"); + createTextField(shrinkPanel, "Default", "w 10:130"); + + createTextField(shrinkPanel, "shrink 0", "newline,shrink 0,w 10:130"); + + createTextField(shrinkPanel, "shp 110", "newline,shp 110,w 10:130"); + createTextField(shrinkPanel, "shp 100,shrink 25", "shp 100,shrink 25,w 10:130"); + createTextField(shrinkPanel, "shp 100,shrink 75", "shp 100,shrink 75,w 10:130"); + + createTextArea(shrinkSash, "Use the slider to see how the components shrink depending on the constraints set on them.\n\n'shp' means Shrink Priority. " + + "Lower values will be shrunk before higer ones and the default value is 100.\n\n'shrink' means Shrink Weight. " + + "Lower values relative to other's means they will shrink less when space is scarse. " + + "Shrink Weight is only relative to components with the same Shrink Priority. Default Shrink Weight is 100.\n\n" + + "The component's minimum size will always be honored.\n\nFor SWT, which doesn't have a component notion of minimum, " + + "preferred or maximum size, those sizes are set explicitly to minimum 10 and preferred 130 pixels.", ""); + + // Grow tab + TabItem growTabPanel = createTabPanel(tabbedPane, "Grow", new FillLayout()); + + SashForm growSash = new SashForm(getComposite(growTabPanel), SWT.HORIZONTAL | SWT.SMOOTH); + growSash.setBackground(new Color(display, 100, 100, 100)); + + Composite growPanel = createPanel(growSash, new MigLayout("nogrid", "[grow]")); + growPanel.setLayoutData("wmin 100"); + + createButton(growPanel, "gp 110, grow", "gp 110, grow, wmax 170"); + createButton(growPanel, "Default (100), grow", "grow, wmax 170"); + createButton(growPanel, "gp 90, grow", "gp 90, grow, wmax 170"); + + createButton(growPanel, "Default Button", "newline"); + + createButton(growPanel, "growx", "newline,growx,wrap"); + + createButton(growPanel, "gp 110, grow", "gp 110, grow, wmax 170"); + createButton(growPanel, "gp 100, grow 25", "gp 100, grow 25, wmax 170"); + createButton(growPanel, "gp 100, grow 75", "gp 100, grow 75, wmax 170"); + + createTextArea(growSash, "'gp' means Grow Priority. " + + "Lower values will be grown before higher ones and the default value is 100.\n\n'grow' means Grow Weight. " + + "Higher values relative to other's means they will grow more when space is up for takes. " + + "Grow Weight is only relative to components with the same Grow Priority. Default Grow Weight is 0 which means " + + "components will normally not grow. \n\nNote that the buttons in the first and last row have max width set to 170 to " + + "emphasize Grow Priority.\n\nThe component's maximum size will always be honored.", ""); + + return tabbedPane; + } + + + // ********************************************************** + // * Helper Methods + // ********************************************************** + +// private final ToolTipListener toolTipListener = new ToolTipListener(); +// private final ConstraintListener constraintListener = new ConstraintListener(); + + private Combo createCombo(Object parent, String[] texts, Object layout) + { + Combo b = new Combo(getComposite(parent), SWT.DROP_DOWN); + for (int i = 0; i < texts.length; i++) + b.add(texts[i]); + b.setLayoutData(layout); + +// configureActiveComponet(b); + + return b; + } + + private Label createLabel(Object parent, String text, Object layout) + { + return createLabel(parent, text, layout, SWT.LEFT); + } + + private Label createLabel(Object parent, String text, Object layout, int style) + { + final Label b = new Label(getComposite(parent), style | DOUBLE_BUFFER); + b.setText(text); + b.setLayoutData(layout != null ? layout : text); +// b.setAlignment(); + +// configureActiveComponet(b); + + return b; + } + + private Text createTextField(Object parent, String text, Object layout) + { + final Text b = new Text(getComposite(parent), SWT.SINGLE | SWT.BORDER | DOUBLE_BUFFER); + b.setText(text); + b.setLayoutData(layout != null ? layout : text); + +// configureActiveComponet(b); + + return b; + } + + private Button createButton(Object parent, String text, Object layout) + { + return createButton(getComposite(parent), text, layout, false); + } + + private Button createButton(Object parent, String text, Object layout, boolean bold) + { + Button b = new Button(getComposite(parent), SWT.PUSH | SWT.NO_BACKGROUND | DOUBLE_BUFFER); + b.setText(text.length() == 0 ? "\"\"" : text); + b.setLayoutData(layout != null ? layout : text); + +// configureActiveComponet(b); + + return b; + } + + private Composite createPanel(Object parent, String text, Object layout) + { + Color bg = new Color(display.getActiveShell().getDisplay(), 255, 255, 255); + Composite panel = new Composite(getComposite(parent), DOUBLE_BUFFER | SWT.BORDER); + panel.setLayout(new MigLayout("fill")); + panel.setBackground(bg); + panel.setLayoutData(layout != null ? layout : text); + text = text.length() == 0 ? "\"\"" : text; + Label label = createLabel(panel, text, "grow", SWT.NO_BACKGROUND | SWT.CENTER); + label.setBackground(bg); + +// configureActiveComponet(panel); + + return panel; + } + + private TabItem createTabPanel(TabFolder parent, String text, Layout lm) + { + Composite panel = new Composite(parent, DOUBLE_BUFFER); +// panel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + TabItem tab = new TabItem(parent, DOUBLE_BUFFER); + tab.setControl(panel); + tab.setText(text); + if (lm != null) + panel.setLayout(lm); + +// configureActiveComponet(panel); + return tab; + } + + private Composite createPanel(Object parent, Layout lm) + { + Composite panel = new Composite(getComposite(parent), DOUBLE_BUFFER); + panel.setLayout(lm); + +// configureActiveComponet(panel); + + return panel; + } + + private Button createToggleButton(Object parent, String text, Object layout) + { + Button b = new Button(getComposite(parent), SWT.TOGGLE | DOUBLE_BUFFER); + b.setText(text.length() == 0 ? "\"\"" : text); + b.setLayoutData(layout != null ? layout : text); + +// configureActiveComponet(b); + + return b; + } + + private Button createCheck(Object parent, String text, Object layout) + { + Button b = new Button(getComposite(parent), SWT.CHECK | DOUBLE_BUFFER); + b.setText(text); + b.setLayoutData(layout != null ? layout : text); +// configureActiveComponet(b); + + return b; + } + + private List createList(Object parent, String text, Object layout) + { + List list = new List(getComposite(parent), DOUBLE_BUFFER | SWT.BORDER); + list.add(text); + list.setLayoutData(layout); + return list; + } + + private StyledText createTextArea(Object parent, String text, String layout) + { + return createTextArea(parent, text, layout, SWT.MULTI | SWT.WRAP | SWT.BORDER | DOUBLE_BUFFER); + } + + private StyledText createTextArea(Object parent, String text, String layout, int style) + { + StyledText ta = new StyledText(getComposite(parent), SWT.MULTI | SWT.WRAP | style | DOUBLE_BUFFER); + ta.setText(text); + ta.setLayoutData(layout != null ? layout : text); + +// configureActiveComponet(ta); + + return ta; + } + + public Composite getComposite(Object c) + { + if (c instanceof Control) + return (Composite) c; + + return (Composite) ((TabItem) c).getControl(); + } + + private Font deriveFont(Control cont, int style, int height) + { + Font f = cont.getFont(); + FontData fd = f.getFontData()[0]; + if (style != SWT.DEFAULT) + fd.setStyle(style); + + if (height != -1) + fd.setHeight(height); + + Font font = new Font(display, fd); + cont.setFont(font); + return font; + } + +// private Control configureActiveComponet(Control c) +// { +// c.addMouseMotionListener(toolTipListener); +// c.addMouseListener(constraintListener); +// return c; +// } + + private void addSeparator(Object panel, String text) + { + Label l = createLabel(panel, text, "gaptop para, span, split 2"); + l.setForeground(new Color(display, 0, 70, 213)); + + Label s = new Label(getComposite(panel), SWT.SEPARATOR | SWT.HORIZONTAL | DOUBLE_BUFFER); + s.setLayoutData("gapleft rel, gaptop para, growx"); + +// configureActiveComponet(s); + } + +// private class ConstraintListener extends MouseAdapter +// { +// public void mousePressed(MouseEvent e) +// { +// if (e.isPopupTrigger()) +// react(e); +// } +// +// public void mouseReleased(MouseEvent e) +// { +// if (e.isPopupTrigger()) +// react(e); +// } +// +// public void react(MouseEvent e) +// { +// Control c = (Control) e.getSource(); +// LayoutManager lm = c.getParent().getLayout(); +// if (lm instanceof SwtMigLayout == false) +// lm = c.getLayout(); +// +// if (lm instanceof SwtMigLayout) { +// MigLayout ffl = (MigLayout) lm; +// boolean isComp = ffl.isManagingComponent(c); +// String compConstr = isComp ? ffl.getComponentConstraints(c) : null; +// String rowsConstr = isComp ? null : ffl.getRowConstraints(); +// String colsConstr = isComp ? null : ffl.getColumnConstraints(); +// String layoutConstr = isComp ? null : ffl.getLayoutConstraints(); +// +// ConstraintsDialog cDlg = new ConstraintsDialog(SwingDemo.this, layoutConstr, rowsConstr, colsConstr, compConstr); +// cDlg.pack(); +// cDlg.setLocationRelativeTo(c); +// +// if (cDlg.showDialog()) { +// try { +// if (isComp) { +// String constrStr = cDlg.componentConstrTF.getText().trim(); +// ffl.setComponentConstraints(c, constrStr); +// if (c instanceof Button) { +// c.setFont(BUTT_FONT); +// ((Button) c).setText(constrStr.length() == 0 ? "<Empty>" : constrStr); +// } +// } else { +// ffl.setLayoutConstraints(cDlg.layoutConstrTF.getText()); +// ffl.setRowConstraints(cDlg.rowsConstrTF.getText()); +// ffl.setColumnConstraints(cDlg.colsConstrTF.getText()); +// } +// } catch(Exception ex) { +// StringWriter sw = new StringWriter(); +// ex.printStackTrace(new PrintWriter(sw)); +// JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(c), sw.toString(), "Error parsing Constraint!", JOptionPane.ERROR_MESSAGE); +// return; +// } +// +// c.invalidate(); +// c.getParent().validate(); +// } +// } +// } +// } +// +// private static class ToolTipListener extends MouseMotionAdapter +// { +// public void mouseMoved(MouseEvent e) +// { +// Control c = (Control) e.getSource(); +// LayoutManager lm = c.getParent().getLayout(); +// if (lm instanceof SwtMigLayout) { +// String constr = ((MigLayout) lm).getComponentConstraints(c); +// c.setToolTipText((constr != null ? ("\"" + constr + "\"") : "null")); +// } +// } +// } +// +// private static class ConstraintsDialog extends JDialog implements ActionListener, KeyEventDispatcher +// { +// private static final Color ERROR_COLOR = new Color(255, 180, 180); +// private final JPanel mainPanel = new JPanel(parent, new SwtMigLayout("fillx,flowy,ins dialog", +// "[fill]", +// "2[]2")); +// final Text layoutConstrTF; +// final Text rowsConstrTF; +// final Text colsConstrTF; +// final Text componentConstrTF; +// +// private final Button okButt = new Button("OK"); +// private final Button cancelButt = new Button("Cancel"); +// +// private boolean okPressed = false; +// +// public ConstraintsDialog(Frame owner, String layoutConstr, String rowsConstr, String colsConstr, String compConstr) +// { +// super(owner, (compConstr != null ? "Edit Component Constraints" : "Edit Container Constraints"), true); +// +// layoutConstrTF = createConstraintField(layoutConstr); +// rowsConstrTF = createConstraintField(rowsConstr); +// colsConstrTF = createConstraintField(colsConstr); +// componentConstrTF = createConstraintField(compConstr); +// +// if (componentConstrTF != null) { +// mainPanel.add(new Label("Component Constraints")); +// mainPanel.add(componentConstrTF); +// } +// +// if (layoutConstrTF != null) { +// mainPanel.add(new Label("Container Layout Constraints")); +// mainPanel.add(layoutConstrTF); +// } +// +// if (rowsConstrTF != null) { +// mainPanel.add(new Label("Container Row Constraints"), "gaptop unrel"); +// mainPanel.add(rowsConstrTF); +// } +// +// if (colsConstrTF != null) { +// mainPanel.add(new Label("Container Column Constraints"), "gaptop unrel"); +// mainPanel.add(colsConstrTF); +// } +// +// mainPanel.add(okButt, "tag ok,split,flowx,gaptop 15"); +// mainPanel.add(cancelButt, "tag cancel,gaptop 15"); +// +// setContentPane(mainPanel); +// +// okButt.addActionListener(this); +// cancelButt.addActionListener(this); +// } +// +// public void addNotify() +// { +// super.addNotify(); +// KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); +// } +// +// public void removeNotify() +// { +// KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this); +// super.removeNotify(); +// } +// +// public boolean dispatchKeyEvent(KeyEvent e) +// { +// if (e.getKeyCode() == KeyEvent.VK_ESCAPE) +// dispose(); +// return false; +// } +// +// public void actionPerformed(ActionEvent e) +// { +// if (e.getSource() == okButt) +// okPressed = true; +// dispose(); +// } +// +// private Text createConstraintField(String text) +// { +// if (text == null) +// return null; +// +// final Text tf = new Text(text, 50); +// tf.setFont(new Font("monospaced", Font.PLAIN, 12)); +// +// tf.addKeyListener(new KeyAdapter() { +// public void keyPressed(KeyEvent e) +// { +// if (e.getKeyCode() == KeyEvent.VK_ENTER) { +// okButt.doClick(); +// return; +// } +// +// javax.swing.Timer timer = new Timer(50, new ActionListener() { +// public void actionPerformed(ActionEvent e) +// { +// String constr = tf.getText(); +// try { +// if (tf == layoutConstrTF) { +// MigLayout.validateLayoutConstraint(constr); +// } else if (tf == rowsConstrTF) { +// MigLayout.validateRowConstraints(constr); +// } else if (tf == colsConstrTF) { +// MigLayout.validateColumnConstraints(constr); +// } else if (tf == componentConstrTF) { +// MigLayout.validateComponentConstraint(constr); +// } +// tf.setBackground(Color.WHITE); +// okButt.setEnabled(true); +// } catch(Exception ex) { +// tf.setBackground(ERROR_COLOR); +// okButt.setEnabled(false); +// } +// } +// }); +// timer.setRepeats(false); +// timer.start(); +// } +// }); +// +// return tf; +// } +// +// private boolean showDialog() +// { +// setVisible(true); +// return okPressed; +// } +// } + +} + + + + diff --git a/prototypes/miglayout/net/miginfocom/examples/Example01.java b/prototypes/miglayout/net/miginfocom/examples/Example01.java index c67d935c..37f19640 100644 --- a/prototypes/miglayout/net/miginfocom/examples/Example01.java +++ b/prototypes/miglayout/net/miginfocom/examples/Example01.java @@ -1,43 +1,43 @@ -package net.miginfocom.examples;
-
-import net.miginfocom.swing.MigLayout;
-
-import javax.swing.*;
-
-/**
- */
-public class Example01
-{
- private static JPanel createPanel()
- {
- JPanel panel = new JPanel(new MigLayout());
-
- panel.add(new JLabel("First Name"));
- panel.add(new JTextField(15));
- panel.add(new JLabel("Surname"), "gap unrelated"); // Unrelated size is resolved per platform
- panel.add(new JTextField(15), "wrap"); // Wraps to the next row
- panel.add(new JLabel("Address"));
- panel.add(new JTextField(), "span, growx"); // Spans cells in row and grows to fit that
-
- return panel;
- }
-
- public static void main(String[] args)
- {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- try {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch (Exception ex) {
- ex.printStackTrace();
- }
-
- JFrame frame = new JFrame("Example 01");
- frame.getContentPane().add(createPanel());
- frame.pack();
- frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- frame.setVisible(true);
- }
- });
- }
-}
+package net.miginfocom.examples; + +import net.miginfocom.swing.MigLayout; + +import javax.swing.*; + +/** + */ +public class Example01 +{ + private static JPanel createPanel() + { + JPanel panel = new JPanel(new MigLayout()); + + panel.add(new JLabel("First Name")); + panel.add(new JTextField(15)); + panel.add(new JLabel("Surname"), "gap unrelated"); // Unrelated size is resolved per platform + panel.add(new JTextField(15), "wrap"); // Wraps to the next row + panel.add(new JLabel("Address")); + panel.add(new JTextField(), "span, growx"); // Spans cells in row and grows to fit that + + return panel; + } + + public static void main(String[] args) + { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception ex) { + ex.printStackTrace(); + } + + JFrame frame = new JFrame("Example 01"); + frame.getContentPane().add(createPanel()); + frame.pack(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setVisible(true); + } + }); + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/AC.java b/prototypes/miglayout/net/miginfocom/layout/AC.java index 34ade72b..fe1e35bf 100644 --- a/prototypes/miglayout/net/miginfocom/layout/AC.java +++ b/prototypes/miglayout/net/miginfocom/layout/AC.java @@ -1,493 +1,493 @@ -package net.miginfocom.layout;
-
-import java.io.*;
-import java.util.ArrayList;
-
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** A constraint that holds the column <b>or</b> row constraints for the grid. It also holds the gaps between the rows and columns.
- * <p>
- * This class is a holder and builder for a number of {@link net.miginfocom.layout.DimConstraint}s.
- * <p>
- * For a more thorough explanation of what these constraints do, and how to build the constriants, see the White Paper or Cheat Sheet at www.migcomponents.com.
- * <p>
- * Note that there are two way to build this constraint. Through String (e.g. <code>"[100]3[200,fill]"</code> or through API (E.g.
- * <code>new AxisConstraint().size("100").gap("3").size("200").fill()</code>.
- */
-public final class AC implements Externalizable
-{
- private final ArrayList<DimConstraint> cList = new ArrayList<DimConstraint>(8);
-
- private transient int curIx = 0;
-
- /** Constructor. Creates an instance that can be configured manually. Will be initialized with a default
- * {@link net.miginfocom.layout.DimConstraint}.
- */
- public AC()
- {
- cList.add(new DimConstraint());
- }
-
- /** Property. The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of.
- * These <code><DimConstraints/code> contains all information in this class.
- * @return The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. A new list and
- * never <code>null</code>.
- */
- public final DimConstraint[] getConstaints()
- {
- return cList.toArray(new DimConstraint[cList.size()]);
- }
-
- /** Sets the different {@link net.miginfocom.layout.DimConstraint}s that this object should consists of.
- * @param constr The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. The list
- * will be copied for storage. <code>null</code> or and emty array will reset the constaints to one <code>DimConstraint</code>
- * with default values.
- */
- public final void setConstaints(DimConstraint[] constr)
- {
- if (constr == null || constr.length < 1 )
- constr = new DimConstraint[] {new DimConstraint()};
-
- cList.clear();
- cList.ensureCapacity(constr.length);
- for (int i = 0; i < constr.length; i++)
- cList.add(constr[i]);
- }
-
- /** Returns the number of rows/columns that this constraints currently have.
- * @return The number of rows/columns that this constraints currently have. At least 1.
- */
- public int getCount()
- {
- return cList.size();
- }
-
- /** Sets the total number of rows/columns to <code>size</code>. If the number of rows/columns is already more
- * than <code>size</code> nothing will happen.
- * @param size The total number of rows/columns
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC count(int size)
- {
- makeSize(size);
- return this;
- }
-
- /** Specifies that the current row/column should not be grid-like. The while row/colum will have its components layed out
- * in one single cell. It is the same as to say that the cells in this column/row will all be merged (a.k.a spanned).
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC noGrid()
- {
- return noGrid(curIx);
- }
-
- /** Specifies that the indicated rows/columns should not be grid-like. The while row/colum will have its components layed out
- * in one single cell. It is the same as to say that the cells in this column/row will all be merged (a.k.a spanned).
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC noGrid(int... indexes)
- {
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setNoGrid(true);
- }
- return this;
- }
-
- /** Sets the current row/column to <code>i</code>. If the current number of rows/columns is less than <code>i</code> a call
- * to {@link #count(int)} will set the size accoringly.
- * <p>
- * The next call to any of the constriant methods (e.g. {@link net.miginfocom.layout.AC#noGrid}) will be carried
- * out on this new row/column.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param i The new current row/column.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC index(int i)
- {
- makeSize(i);
- curIx = i;
- return this;
- }
-
- /** Specifies that the current row/column's component should grow by default. It does not affect the size of the row/column.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC fill()
- {
- return fill(curIx);
- }
-
- /** Specifies that the indicated rows'/columns' component should grow by default. It does not affect the size of the row/column.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC fill(int... indexes)
- {
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setFill(true);
- }
- return this;
- }
-
-// /** Specifies that the current row/column should be put in the end group <code>s</code> and will thus share the same ending
-// * coordinate within the group.
-// * <p>
-// * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
-// * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
-// * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
-// */
-// public final AxisConstraint endGroup(String s)
-// {
-// return endGroup(s, curIx);
-// }
-//
-// /** Specifies that the indicated rows/columns should be put in the end group <code>s</code> and will thus share the same ending
-// * coordinate within the group.
-// * <p>
-// * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
-// * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
-// * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
-// * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
-// */
-// public final AxisConstraint endGroup(String s, int... indexes)
-// {
-// for (int i = indexes.length - 1; i >= 0; i--) {
-// int ix = indexes[i];
-// makeSize(ix);
-// cList.get(ix).setEndGroup(s);
-// }
-// return this;
-// }
-
- /** Specifies that the current row/column should be put in the size group <code>s</code> and will thus share the same size
- * constraints as the other components in the group.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC sizeGroup(String s)
- {
- return sizeGroup(s, curIx);
- }
-
- /** Specifies that the indicated rows/columns should be put in the size group <code>s</code> and will thus share the same size
- * constraints as the other components in the group.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC sizeGroup(String s, int... indexes)
- {
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setSizeGroup(s);
- }
- return this;
- }
-
- /** Specifies the current row/column's min and/or preferred and/or max size. E.g. <code>"10px"</code> or <code>"50:100:200"</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s The minimum and/or preferred and/or maximum size of this row. The string will be interpreted
- * as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC size(String s)
- {
- return size(s, curIx);
- }
-
- /** Specifies the indicated rows'/columns' min and/or preferred and/or max size. E.g. <code>"10px"</code> or <code>"50:100:200"</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The minimum and/or preferred and/or maximum size of this row. The string will be interpreted
- * as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC size(String size, int... indexes)
- {
- BoundSize bs = ConstraintParser.parseBoundSize(size, false, true);
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setSize(bs);
- }
- return this;
- }
-
- /** Specifies the gap size to be the default one <b>AND</b> moves to the next column/row. The method is called <code>.gap()</code>
- * rather the more natural <code>.next()</code> to indicate that it is very much related to the other <code>.gap(..)</code> methods.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC gap()
- {
- curIx++;
- return this;
- }
-
- /** Specifies the gap size to <code>size</code> <b>AND</b> moves to the next column/row.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column.
- * The string will be interpreted as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC gap(String size)
- {
- return gap(size, curIx++);
- }
-
- /** Specifies the indicated rows'/columns' gap size to <code>size</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column.
- * The string will be interpreted as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC gap(String size, int... indexes)
- {
- BoundSize bsa = size != null ? ConstraintParser.parseBoundSize(size, true, true) : null;
-
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- if (bsa != null)
- cList.get(ix).setGapAfter(bsa);
- }
- return this;
- }
-
- /** Specifies the current row/column's columns default alignment <b>for its components</b>. It does not affect the positioning
- * or size of the columns/row itself. For columns it is the horizonal alignment (e.g. "left") and for rows it is the vertical
- * alignment (e.g. "top").
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param side The default side to align the components. E.g. "top" or "left", or "leading" or "trailing" or "bottom" or "right".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC align(String side)
- {
- return align(side, curIx);
- }
-
- /** Specifies the indicated rows'/columns' columns default alignment <b>for its components</b>. It does not affect the positioning
- * or size of the columns/row itself. For columns it is the horizonal alignment (e.g. "left") and for rows it is the vertical
- * alignment (e.g. "top").
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param side The default side to align the components. E.g. "top" or "left", or "before" or "after" or "bottom" or "right".
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC align(String side, int... indexes)
- {
- UnitValue al = ConstraintParser.parseAlignKeywords(side, true);
- if (al == null)
- al = ConstraintParser.parseAlignKeywords(side, false);
-
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setAlign(al);
- }
- return this;
- }
-
- /** Specifies the current row/column's grow priority.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The new grow priority.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC growPrio(int p)
- {
- return growPrio(p, curIx);
- }
-
- /** Specifies the indicated rows'/columns' grow priority.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The new grow priority.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC growPrio(int p, int... indexes)
- {
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setGrowPriority(p);
- }
- return this;
- }
-
- /** Specifies the current row/column's grow weight within columns/rows with the same <code>grow priority</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param w The new grow weight.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC grow(float w)
- {
- return grow(w, curIx);
- }
-
- /** Specifies the indicated rows'/columns' grow weight within columns/rows with the same <code>grow priority</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param w The new grow weight.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC grow(float w, int... indexes)
- {
- Float gw = new Float(w);
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setGrow(gw);
- }
- return this;
- }
-
- /** Specifies the current row/column's shrink priority.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The new shrink priority.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC shrinkPrio(int p)
- {
- return shrinkPrio(p, curIx);
- }
-
- /** Specifies the indicated rows'/columns' shrink priority.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The new shrink priority.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC shrinkPrio(int p, int... indexes)
- {
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setShrinkPriority(p);
- }
- return this;
- }
-
- /** Specifies that the current row/column's shrink weight withing the columns/rows with the same <code>shrink priority</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
- * @param w The shrink weight.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC shrinkWeight(float w)
- {
- return shrinkWeight(w, curIx);
- }
-
- /** Specifies the indicated rows'/columns' shrink weight withing the columns/rows with the same <code>shrink priority</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com.
- * @param w The shrink weight.
- * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>.
- */
- public final AC shrinkWeight(float w, int... indexes)
- {
- Float sw = new Float(w);
- for (int i = indexes.length - 1; i >= 0; i--) {
- int ix = indexes[i];
- makeSize(ix);
- cList.get(ix).setShrink(sw);
- }
- return this;
- }
-
- private void makeSize(int sz)
- {
- if (cList.size() <= sz) {
- cList.ensureCapacity(sz);
- for (int i = cList.size(); i <= sz; i++)
- cList.add(new DimConstraint());
- }
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
-
- public void writeExternal(ObjectOutput out) throws IOException
- {
- if (getClass() == AC.class)
- LayoutUtil.writeAsXML(out, this);
- }
+package net.miginfocom.layout; + +import java.io.*; +import java.util.ArrayList; + +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** A constraint that holds the column <b>or</b> row constraints for the grid. It also holds the gaps between the rows and columns. + * <p> + * This class is a holder and builder for a number of {@link net.miginfocom.layout.DimConstraint}s. + * <p> + * For a more thorough explanation of what these constraints do, and how to build the constriants, see the White Paper or Cheat Sheet at www.migcomponents.com. + * <p> + * Note that there are two way to build this constraint. Through String (e.g. <code>"[100]3[200,fill]"</code> or through API (E.g. + * <code>new AxisConstraint().size("100").gap("3").size("200").fill()</code>. + */ +public final class AC implements Externalizable +{ + private final ArrayList<DimConstraint> cList = new ArrayList<DimConstraint>(8); + + private transient int curIx = 0; + + /** Constructor. Creates an instance that can be configured manually. Will be initialized with a default + * {@link net.miginfocom.layout.DimConstraint}. + */ + public AC() + { + cList.add(new DimConstraint()); + } + + /** Property. The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. + * These <code><DimConstraints/code> contains all information in this class. + * @return The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. A new list and + * never <code>null</code>. + */ + public final DimConstraint[] getConstaints() + { + return cList.toArray(new DimConstraint[cList.size()]); + } + + /** Sets the different {@link net.miginfocom.layout.DimConstraint}s that this object should consists of. + * @param constr The different {@link net.miginfocom.layout.DimConstraint}s that this object consists of. The list + * will be copied for storage. <code>null</code> or and emty array will reset the constaints to one <code>DimConstraint</code> + * with default values. + */ + public final void setConstaints(DimConstraint[] constr) + { + if (constr == null || constr.length < 1 ) + constr = new DimConstraint[] {new DimConstraint()}; + + cList.clear(); + cList.ensureCapacity(constr.length); + for (int i = 0; i < constr.length; i++) + cList.add(constr[i]); + } + + /** Returns the number of rows/columns that this constraints currently have. + * @return The number of rows/columns that this constraints currently have. At least 1. + */ + public int getCount() + { + return cList.size(); + } + + /** Sets the total number of rows/columns to <code>size</code>. If the number of rows/columns is already more + * than <code>size</code> nothing will happen. + * @param size The total number of rows/columns + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC count(int size) + { + makeSize(size); + return this; + } + + /** Specifies that the current row/column should not be grid-like. The while row/colum will have its components layed out + * in one single cell. It is the same as to say that the cells in this column/row will all be merged (a.k.a spanned). + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC noGrid() + { + return noGrid(curIx); + } + + /** Specifies that the indicated rows/columns should not be grid-like. The while row/colum will have its components layed out + * in one single cell. It is the same as to say that the cells in this column/row will all be merged (a.k.a spanned). + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC noGrid(int... indexes) + { + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setNoGrid(true); + } + return this; + } + + /** Sets the current row/column to <code>i</code>. If the current number of rows/columns is less than <code>i</code> a call + * to {@link #count(int)} will set the size accoringly. + * <p> + * The next call to any of the constriant methods (e.g. {@link net.miginfocom.layout.AC#noGrid}) will be carried + * out on this new row/column. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param i The new current row/column. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC index(int i) + { + makeSize(i); + curIx = i; + return this; + } + + /** Specifies that the current row/column's component should grow by default. It does not affect the size of the row/column. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC fill() + { + return fill(curIx); + } + + /** Specifies that the indicated rows'/columns' component should grow by default. It does not affect the size of the row/column. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC fill(int... indexes) + { + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setFill(true); + } + return this; + } + +// /** Specifies that the current row/column should be put in the end group <code>s</code> and will thus share the same ending +// * coordinate within the group. +// * <p> +// * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. +// * @param s A name to associate on the group that should be the same for other rows/columns in the same group. +// * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. +// */ +// public final AxisConstraint endGroup(String s) +// { +// return endGroup(s, curIx); +// } +// +// /** Specifies that the indicated rows/columns should be put in the end group <code>s</code> and will thus share the same ending +// * coordinate within the group. +// * <p> +// * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. +// * @param s A name to associate on the group that should be the same for other rows/columns in the same group. +// * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. +// * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. +// */ +// public final AxisConstraint endGroup(String s, int... indexes) +// { +// for (int i = indexes.length - 1; i >= 0; i--) { +// int ix = indexes[i]; +// makeSize(ix); +// cList.get(ix).setEndGroup(s); +// } +// return this; +// } + + /** Specifies that the current row/column should be put in the size group <code>s</code> and will thus share the same size + * constraints as the other components in the group. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s A name to associate on the group that should be the same for other rows/columns in the same group. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC sizeGroup(String s) + { + return sizeGroup(s, curIx); + } + + /** Specifies that the indicated rows/columns should be put in the size group <code>s</code> and will thus share the same size + * constraints as the other components in the group. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s A name to associate on the group that should be the same for other rows/columns in the same group. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC sizeGroup(String s, int... indexes) + { + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setSizeGroup(s); + } + return this; + } + + /** Specifies the current row/column's min and/or preferred and/or max size. E.g. <code>"10px"</code> or <code>"50:100:200"</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s The minimum and/or preferred and/or maximum size of this row. The string will be interpreted + * as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC size(String s) + { + return size(s, curIx); + } + + /** Specifies the indicated rows'/columns' min and/or preferred and/or max size. E.g. <code>"10px"</code> or <code>"50:100:200"</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The minimum and/or preferred and/or maximum size of this row. The string will be interpreted + * as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC size(String size, int... indexes) + { + BoundSize bs = ConstraintParser.parseBoundSize(size, false, true); + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setSize(bs); + } + return this; + } + + /** Specifies the gap size to be the default one <b>AND</b> moves to the next column/row. The method is called <code>.gap()</code> + * rather the more natural <code>.next()</code> to indicate that it is very much related to the other <code>.gap(..)</code> methods. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC gap() + { + curIx++; + return this; + } + + /** Specifies the gap size to <code>size</code> <b>AND</b> moves to the next column/row. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column. + * The string will be interpreted as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC gap(String size) + { + return gap(size, curIx++); + } + + /** Specifies the indicated rows'/columns' gap size to <code>size</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size minimum and/or preferred and/or maximum size of the gap between this and the next row/column. + * The string will be interpreted as a <b>BoundSize</b>. For more info on how <b>BoundSize</b> is formatted see the documentation. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC gap(String size, int... indexes) + { + BoundSize bsa = size != null ? ConstraintParser.parseBoundSize(size, true, true) : null; + + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + if (bsa != null) + cList.get(ix).setGapAfter(bsa); + } + return this; + } + + /** Specifies the current row/column's columns default alignment <b>for its components</b>. It does not affect the positioning + * or size of the columns/row itself. For columns it is the horizonal alignment (e.g. "left") and for rows it is the vertical + * alignment (e.g. "top"). + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param side The default side to align the components. E.g. "top" or "left", or "leading" or "trailing" or "bottom" or "right". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC align(String side) + { + return align(side, curIx); + } + + /** Specifies the indicated rows'/columns' columns default alignment <b>for its components</b>. It does not affect the positioning + * or size of the columns/row itself. For columns it is the horizonal alignment (e.g. "left") and for rows it is the vertical + * alignment (e.g. "top"). + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param side The default side to align the components. E.g. "top" or "left", or "before" or "after" or "bottom" or "right". + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC align(String side, int... indexes) + { + UnitValue al = ConstraintParser.parseAlignKeywords(side, true); + if (al == null) + al = ConstraintParser.parseAlignKeywords(side, false); + + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setAlign(al); + } + return this; + } + + /** Specifies the current row/column's grow priority. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The new grow priority. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC growPrio(int p) + { + return growPrio(p, curIx); + } + + /** Specifies the indicated rows'/columns' grow priority. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The new grow priority. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC growPrio(int p, int... indexes) + { + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setGrowPriority(p); + } + return this; + } + + /** Specifies the current row/column's grow weight within columns/rows with the same <code>grow priority</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param w The new grow weight. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC grow(float w) + { + return grow(w, curIx); + } + + /** Specifies the indicated rows'/columns' grow weight within columns/rows with the same <code>grow priority</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param w The new grow weight. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC grow(float w, int... indexes) + { + Float gw = new Float(w); + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setGrow(gw); + } + return this; + } + + /** Specifies the current row/column's shrink priority. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The new shrink priority. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC shrinkPrio(int p) + { + return shrinkPrio(p, curIx); + } + + /** Specifies the indicated rows'/columns' shrink priority. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The new shrink priority. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC shrinkPrio(int p, int... indexes) + { + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setShrinkPriority(p); + } + return this; + } + + /** Specifies that the current row/column's shrink weight withing the columns/rows with the same <code>shrink priority</code>. + * <p> + * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com. + * @param w The shrink weight. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC shrinkWeight(float w) + { + return shrinkWeight(w, curIx); + } + + /** Specifies the indicated rows'/columns' shrink weight withing the columns/rows with the same <code>shrink priority</code>. + * <p> + * For a more thorough explanation of what this constraint does see the White Paper or Cheat Sheet at www.migcomponents.com. + * @param w The shrink weight. + * @param indexes The index(es) (0-based) of the columns/rows that should be affected by this constraint. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new AxisConstraint().noGrid().gap().fill()</code>. + */ + public final AC shrinkWeight(float w, int... indexes) + { + Float sw = new Float(w); + for (int i = indexes.length - 1; i >= 0; i--) { + int ix = indexes[i]; + makeSize(ix); + cList.get(ix).setShrink(sw); + } + return this; + } + + private void makeSize(int sz) + { + if (cList.size() <= sz) { + cList.ensureCapacity(sz); + for (int i = cList.size(); i <= sz; i++) + cList.add(new DimConstraint()); + } + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + if (getClass() == AC.class) + LayoutUtil.writeAsXML(out, this); + } }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/layout/BoundSize.java b/prototypes/miglayout/net/miginfocom/layout/BoundSize.java index a5eeb32f..6da6eb40 100644 --- a/prototypes/miglayout/net/miginfocom/layout/BoundSize.java +++ b/prototypes/miglayout/net/miginfocom/layout/BoundSize.java @@ -1,246 +1,246 @@ -package net.miginfocom.layout;
-
-import java.beans.Encoder;
-import java.beans.Expression;
-import java.beans.PersistenceDelegate;
-import java.io.*;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** A size that contains minimum, preferred and maximum size of type {@link UnitValue}.
- * <p>
- * This class is a simple value container and it is immutable.
- * <p>
- * If a size is missing (i.e., <code>null</code>) that boundary should be considered "not in use".
- * <p>
- * You can create a BoundSize from a String with the use of {@link ConstraintParser#parseBoundSize(String, boolean, boolean)}
- */
-public class BoundSize implements Serializable
-{
- public static final BoundSize ZERO_PIXEL = new BoundSize(UnitValue.ZERO, "0px");
-
- private final transient UnitValue min;
- private final transient UnitValue pref;
- private final transient UnitValue max;
- private final transient boolean gapPush;
-
- /** Constructor that use the same value for min/preferred/max size.
- * @param minMaxPref The value to use for min/preferred/max size.
- * @param createString The string used to create the BoundsSize.
- */
- public BoundSize(UnitValue minMaxPref, String createString)
- {
- this(minMaxPref, minMaxPref, minMaxPref, createString);
- }
-
- /** Constructor. <b>This method is here for serilization only and should normally not be used. Use
- * {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead.
- * @param min The minimum size. May be <code>null</code>.
- * @param preferred The preferred size. May be <code>null</code>.
- * @param max The maximum size. May be <code>null</code>.
- * @param createString The string used to create the BoundsSize.
- */
- public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, String createString) // Bound to old delegate!!!!!
- {
- this(min, preferred, max, false, createString);
- }
-
- /** Constructor. <b>This method is here for serilization only and should normally not be used. Use
- * {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead.
- * @param min The minimum size. May be <code>null</code>.
- * @param preferred The preferred size. May be <code>null</code>.
- * @param max The maximum size. May be <code>null</code>.
- * @param gapPush If the size should be hinted as "pushing" and thus want to occupy free space if noone else is claiming it.
- * @param createString The string used to create the BoundsSize.
- */
- public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, boolean gapPush, String createString)
- {
- this.min = min;
- this.pref = preferred;
- this.max = max;
- this.gapPush = gapPush;
-
- LayoutUtil.putCCString(this, createString); // this escapes!!
- }
-
- /** Returns the minimum size as sent into the constructor.
- * @return The minimum size as sent into the constructor. May be <code>null</code>.
- */
- public final UnitValue getMin()
- {
- return min;
- }
-
- /** Returns the preferred size as sent into the constructor.
- * @return The preferred size as sent into the constructor. May be <code>null</code>.
- */
- public final UnitValue getPreferred()
- {
- return pref;
- }
-
- /** Returns the maximum size as sent into the constructor.
- * @return The maximum size as sent into the constructor. May be <code>null</code>.
- */
- public final UnitValue getMax()
- {
- return max;
- }
-
- /** If the size should be hinted as "pushing" and thus want to occupy free space if noone else is claiming it.
- * @return The value.
- */
- public boolean getGapPush()
- {
- return gapPush;
- }
-
- /** Returns if this bound size has no min, preferred and maximum size set (they are all <code>null</code>)
- * @return If unset.
- */
- public boolean isUnset()
- {
- return pref == null && min == null && max == null;
- }
-
- /** Returns the minimum, preferred or maximum size for this bounded size.
- * @param sizeType The type. <code>LayoutUtil.MIN</code>, <code>LayoutUtil.PREF</code> or <code>LayoutUtil.MAX</code>.
- * @return
- */
- final UnitValue getSize(int sizeType)
- {
- switch(sizeType) {
- case LayoutUtil.MIN:
- return min;
- case LayoutUtil.PREF:
- return pref;
- case LayoutUtil.MAX:
- return max;
- default:
- throw new IllegalArgumentException("Unknown size: " + sizeType);
- }
- }
-
- /** Convert the bound sizes to pixels.
- * <p>
- * <code>null</code> bound sizes will be 0 for min and preferred and {@link net.miginfocom.layout.LayoutUtil#INF} for max.
- * @param refSize The reference size.
- * @param parent The parent. Not <code>null</code>.
- * @param comp The component, if applicable, can be <code>null</code>.
- * @return An array of lenth three (min,pref,max).
- */
- final int[] getPixelSizes(float refSize, ContainerWrapper parent, ComponentWrapper comp)
- {
- return new int[] {
- min != null ? min.getPixels(refSize, parent, comp) : 0,
- pref != null ? pref.getPixels(refSize, parent, comp) : 0,
- max != null ? max.getPixels(refSize, parent, comp) : LayoutUtil.INF
- };
- }
-
- /** Returns the a constraint string that can be re-parsed to be the exact same UnitValue.
- * @return A String. Never <code>null</code>.
- */
- String getConstraintString()
- {
- String cs = LayoutUtil.getCCString(this);
- if (cs != null)
- return cs;
-
- if (min == pref && pref == max)
- return min != null ? (min.getConstraintString() + "!") : "null";
-
- StringBuilder sb = new StringBuilder(16);
-
- if (min != null)
- sb.append(min.getConstraintString()).append(':');
-
- if (pref != null) {
- sb.append(pref.getConstraintString());
- } else if (min != null) {
- sb.append('n');
- }
-
- if (max != null)
- sb.append(sb.length() == 0 ? "::" : ":").append(max.getConstraintString());
-
- if (gapPush) {
- if (sb.length() > 0)
- sb.append(':');
- sb.append("push");
- }
-
- return sb.toString();
- }
-
- static {
- LayoutUtil.setDelegate(BoundSize.class, new PersistenceDelegate() {
- protected Expression instantiate(Object oldInstance, Encoder out)
- {
- BoundSize bs = (BoundSize) oldInstance;
- if (Grid.TEST_GAPS) {
- return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
- bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getGapPush(), bs.getConstraintString()
- });
- } else {
- return new Expression(oldInstance, BoundSize.class, "new", new Object[] {
- bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getConstraintString()
- });
- }
- }
- });
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private static final long serialVersionUID = 1L;
-
- protected Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- private void writeObject(ObjectOutputStream out) throws IOException
- {
- if (getClass() == BoundSize.class)
- LayoutUtil.writeAsXML(out, this);
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
+package net.miginfocom.layout; + +import java.beans.Encoder; +import java.beans.Expression; +import java.beans.PersistenceDelegate; +import java.io.*; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** A size that contains minimum, preferred and maximum size of type {@link UnitValue}. + * <p> + * This class is a simple value container and it is immutable. + * <p> + * If a size is missing (i.e., <code>null</code>) that boundary should be considered "not in use". + * <p> + * You can create a BoundSize from a String with the use of {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} + */ +public class BoundSize implements Serializable +{ + public static final BoundSize ZERO_PIXEL = new BoundSize(UnitValue.ZERO, "0px"); + + private final transient UnitValue min; + private final transient UnitValue pref; + private final transient UnitValue max; + private final transient boolean gapPush; + + /** Constructor that use the same value for min/preferred/max size. + * @param minMaxPref The value to use for min/preferred/max size. + * @param createString The string used to create the BoundsSize. + */ + public BoundSize(UnitValue minMaxPref, String createString) + { + this(minMaxPref, minMaxPref, minMaxPref, createString); + } + + /** Constructor. <b>This method is here for serilization only and should normally not be used. Use + * {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead. + * @param min The minimum size. May be <code>null</code>. + * @param preferred The preferred size. May be <code>null</code>. + * @param max The maximum size. May be <code>null</code>. + * @param createString The string used to create the BoundsSize. + */ + public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, String createString) // Bound to old delegate!!!!! + { + this(min, preferred, max, false, createString); + } + + /** Constructor. <b>This method is here for serilization only and should normally not be used. Use + * {@link ConstraintParser#parseBoundSize(String, boolean, boolean)} instead. + * @param min The minimum size. May be <code>null</code>. + * @param preferred The preferred size. May be <code>null</code>. + * @param max The maximum size. May be <code>null</code>. + * @param gapPush If the size should be hinted as "pushing" and thus want to occupy free space if noone else is claiming it. + * @param createString The string used to create the BoundsSize. + */ + public BoundSize(UnitValue min, UnitValue preferred, UnitValue max, boolean gapPush, String createString) + { + this.min = min; + this.pref = preferred; + this.max = max; + this.gapPush = gapPush; + + LayoutUtil.putCCString(this, createString); // this escapes!! + } + + /** Returns the minimum size as sent into the constructor. + * @return The minimum size as sent into the constructor. May be <code>null</code>. + */ + public final UnitValue getMin() + { + return min; + } + + /** Returns the preferred size as sent into the constructor. + * @return The preferred size as sent into the constructor. May be <code>null</code>. + */ + public final UnitValue getPreferred() + { + return pref; + } + + /** Returns the maximum size as sent into the constructor. + * @return The maximum size as sent into the constructor. May be <code>null</code>. + */ + public final UnitValue getMax() + { + return max; + } + + /** If the size should be hinted as "pushing" and thus want to occupy free space if noone else is claiming it. + * @return The value. + */ + public boolean getGapPush() + { + return gapPush; + } + + /** Returns if this bound size has no min, preferred and maximum size set (they are all <code>null</code>) + * @return If unset. + */ + public boolean isUnset() + { + return pref == null && min == null && max == null; + } + + /** Returns the minimum, preferred or maximum size for this bounded size. + * @param sizeType The type. <code>LayoutUtil.MIN</code>, <code>LayoutUtil.PREF</code> or <code>LayoutUtil.MAX</code>. + * @return + */ + final UnitValue getSize(int sizeType) + { + switch(sizeType) { + case LayoutUtil.MIN: + return min; + case LayoutUtil.PREF: + return pref; + case LayoutUtil.MAX: + return max; + default: + throw new IllegalArgumentException("Unknown size: " + sizeType); + } + } + + /** Convert the bound sizes to pixels. + * <p> + * <code>null</code> bound sizes will be 0 for min and preferred and {@link net.miginfocom.layout.LayoutUtil#INF} for max. + * @param refSize The reference size. + * @param parent The parent. Not <code>null</code>. + * @param comp The component, if applicable, can be <code>null</code>. + * @return An array of lenth three (min,pref,max). + */ + final int[] getPixelSizes(float refSize, ContainerWrapper parent, ComponentWrapper comp) + { + return new int[] { + min != null ? min.getPixels(refSize, parent, comp) : 0, + pref != null ? pref.getPixels(refSize, parent, comp) : 0, + max != null ? max.getPixels(refSize, parent, comp) : LayoutUtil.INF + }; + } + + /** Returns the a constraint string that can be re-parsed to be the exact same UnitValue. + * @return A String. Never <code>null</code>. + */ + String getConstraintString() + { + String cs = LayoutUtil.getCCString(this); + if (cs != null) + return cs; + + if (min == pref && pref == max) + return min != null ? (min.getConstraintString() + "!") : "null"; + + StringBuilder sb = new StringBuilder(16); + + if (min != null) + sb.append(min.getConstraintString()).append(':'); + + if (pref != null) { + sb.append(pref.getConstraintString()); + } else if (min != null) { + sb.append('n'); + } + + if (max != null) + sb.append(sb.length() == 0 ? "::" : ":").append(max.getConstraintString()); + + if (gapPush) { + if (sb.length() > 0) + sb.append(':'); + sb.append("push"); + } + + return sb.toString(); + } + + static { + LayoutUtil.setDelegate(BoundSize.class, new PersistenceDelegate() { + protected Expression instantiate(Object oldInstance, Encoder out) + { + BoundSize bs = (BoundSize) oldInstance; + if (Grid.TEST_GAPS) { + return new Expression(oldInstance, BoundSize.class, "new", new Object[] { + bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getGapPush(), bs.getConstraintString() + }); + } else { + return new Expression(oldInstance, BoundSize.class, "new", new Object[] { + bs.getMin(), bs.getPreferred(), bs.getMax(), bs.getConstraintString() + }); + } + } + }); + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private static final long serialVersionUID = 1L; + + protected Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + private void writeObject(ObjectOutputStream out) throws IOException + { + if (getClass() == BoundSize.class) + LayoutUtil.writeAsXML(out, this); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/layout/CC.java b/prototypes/miglayout/net/miginfocom/layout/CC.java index 1fe75e2c..304f36ce 100644 --- a/prototypes/miglayout/net/miginfocom/layout/CC.java +++ b/prototypes/miglayout/net/miginfocom/layout/CC.java @@ -1,1543 +1,1543 @@ -package net.miginfocom.layout;
-
-import java.io.*;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** A simple value holder for one component's constraint.
- */
-public final class CC implements Externalizable
-{
- private static final BoundSize DEF_GAP = new BoundSize(null, null); // Only used to denote default wrap/newline gap.
-
- static final String[] DOCK_SIDES = {"north", "west", "south", "east"};
-
- // See the getters and setters for information about the properties below.
-
- private int dock = -1;
-
- private UnitValue[] pos = null; // [x1, y1, x2, y2]
-
- private UnitValue[] padding = null; // top, left, bottom, right
-
- private Boolean flowX = null;
-
- private int skip = 0;
-
- private int split = 1;
-
- private int spanX = 1, spanY = 1;
-
- private int cellX = -1, cellY = 0; // If cellX is -1 then cellY is also considered -1. cellY is never negative.
-
- private String tag = null;
-
- private String id = null;
-
- private int hideMode = -1;
-
- private DimConstraint hor = new DimConstraint();
-
- private DimConstraint ver = new DimConstraint();
-
- private BoundSize newline = null;
-
- private BoundSize wrap = null;
-
- private boolean boundsInGrid = true;
-
- private boolean external = false;
-
- private Float pushX = null, pushY = null;
-
-
- /** Empty constructor.
- */
- public CC()
- {
- }
-
- // **********************************************************
- // Chaining constraint setters
- // **********************************************************
-
- /** Specifies that the component should be put in the end group <code>s</code> and will thus share the same ending
- * coordinate as them within the group.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC endGroupX(String s)
- {
- hor.setEndGroup(s);
- return this;
- }
-
- /** Specifies that the component should be put in the size group <code>s</code> and will thus share the same size
- * as them within the group.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s A name to associate on the group that should be the same for other rows/columns in the same group.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC sizeGroupX(String s)
- {
- hor.setSizeGroup(s);
- return this;
- }
-
- /** The minimum size for the component. The value will override any value that is set on the component itself.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC minWidth(String size)
- {
- hor.setSize(LayoutUtil.derive(hor.getSize(), ConstraintParser.parseUnitValue(size, true), null, null));
- return this;
- }
-
- /** The size for the component as a min and/or preferref and/or maximum size. The value will override any value that is set on
- * the component itself.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The size expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC width(String size)
- {
- hor.setSize(ConstraintParser.parseBoundSize(size, false, true));
- return this;
- }
-
- /** The maximum size for the component. The value will override any value that is set on the component itself.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC maxWidth(String size)
- {
- hor.setSize(LayoutUtil.derive(hor.getSize(), null, null, ConstraintParser.parseUnitValue(size, true)));
- return this;
- }
-
-
- /** The horizontal gap before and/or after the component. The gap is towards cell bounds and/or other component bounds.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param before The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
- * @param after The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC gapX(String before, String after)
- {
- if (before != null)
- hor.setGapBefore(ConstraintParser.parseBoundSize(before, true, true));
-
- if (after != null)
- hor.setGapAfter(ConstraintParser.parseBoundSize(after, true, true));
-
- return this;
- }
-
- /** Same functionality as <code>getHorizontal().setAlign(ConstraintParser.parseUnitValue(unitValue, true))</code> only this method
- * returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param align The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC alignX(String align)
- {
- hor.setAlign(ConstraintParser.parseUnitValueOrAlign(align, true, null));
- return this;
- }
-
- /** The grow priority compared to other components in the same cell.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The grow priority.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC growPrioX(int p)
- {
- hor.setGrowPriority(p);
- return this;
- }
-
- /** Grow weight for the component horizontally. It default to weight <code>100</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #growX(float)
- */
- public final CC growX()
- {
- hor.setGrow(ResizeConstraint.WEIGHT_100);
- return this;
- }
-
- /** Grow weight for the component horizontally.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param w The new grow weight.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC growX(float w)
- {
- hor.setGrow(new Float(w));
- return this;
- }
-
- /** The shrink priority compared to other components in the same cell.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The shrink priority.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC shrinkPrioX(int p)
- {
- hor.setShrinkPriority(p);
- return this;
- }
-
- /** Shrink weight for the component horizontally.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param w The new shrink weight.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC shrinkX(float w)
- {
- hor.setShrink(new Float(w));
- return this;
- }
-
- /** The end group that this componet should be placed in.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s The name of the group. If <code>null</code> that means no group (default)
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC endGroupY(String s)
- {
- ver.setEndGroup(s);
- return this;
- }
-
- /** The size group that this componet should be placed in.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s The name of the group. If <code>null</code> that means no group (default)
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC sizeGroupY(String s)
- {
- ver.setSizeGroup(s);
- return this;
- }
-
- /** The minimum size for the component. The value will override any value that is set on the component itself.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC minHeight(String size)
- {
- ver.setSize(LayoutUtil.derive(ver.getSize(), ConstraintParser.parseUnitValue(size, false), null, null));
- return this;
- }
-
- /** The size for the component as a min and/or preferref and/or maximum size. The value will override any value that is set on
- * the component itself.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The size expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC height(String size)
- {
- ver.setSize(ConstraintParser.parseBoundSize(size, false, false));
- return this;
- }
-
- /** The maximum size for the component. The value will override any value that is set on the component itself.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC maxHeight(String size)
- {
- ver.setSize(LayoutUtil.derive(ver.getSize(), null, null, ConstraintParser.parseUnitValue(size, false)));
- return this;
- }
-
- /** The vertical gap before (normally above) and/or after (normally below) the component. The gap is towards cell bounds and/or other component bounds.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param before The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
- * @param after The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC gapY(String before, String after)
- {
- if (before != null)
- ver.setGapBefore(ConstraintParser.parseBoundSize(before, true, false));
-
- if (after != null)
- ver.setGapAfter(ConstraintParser.parseBoundSize(after, true, false));
-
- return this;
- }
-
- /** Same functionality as <code>getVertical().setAlign(ConstraintParser.parseUnitValue(unitValue, true))</code> only this method
- * returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param align The align keyword or for instance "100px". E.g "top" or "bottom".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC alignY(String align)
- {
- ver.setAlign(ConstraintParser.parseUnitValueOrAlign(align, false, null));
- return this;
- }
-
- /** The grow priority compared to other components in the same cell.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The grow priority.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC growPrioY(int p)
- {
- ver.setGrowPriority(p);
- return this;
- }
-
- /** Grow weight for the component vertically. Defaults to <code>100</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #growY(Float)
- */
- public final CC growY()
- {
- ver.setGrow(ResizeConstraint.WEIGHT_100);
- return this;
- }
-
- /** Grow weight for the component vertically.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param w The new grow weight.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC growY(Float w)
- {
- ver.setGrow(w);
- return this;
- }
-
- /** The shrink priority compared to other components in the same cell.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The shrink priority.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC shrinkPrioY(int p)
- {
- ver.setShrinkPriority(p);
- return this;
- }
-
- /** Shrink weight for the component horizontally.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param w The new shrink weight.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC shrinkY(float w)
- {
- ver.setShrink(new Float(w));
- return this;
- }
-
- /** How this component, if hidden (not visible), should be treated.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param mode The mode. Default to the mode in the {@link net.miginfocom.layout.LC}.
- * 0 == Normal. Bounds will be calculated as if the component was visible.<br>
- * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
- * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
- * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC hideMode(int mode)
- {
- setHideMode(mode);
- return this;
- }
-
- /** The id used to reference this component in some constraints.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
- * The dot should never be first or last if present.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- */
- public final CC id(String s)
- {
- setId(s);
- return this;
- }
-
- /** Same functionality as {@link #setTag(String tag)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param tag The new tag. May be <code>null</code>.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setTag(String)
- */
- public final CC tag(String tag)
- {
- setTag(tag);
- return this;
- }
-
- /** Same functionality as {@link #setCellX(int col)} and {@link #setCellY(int row)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param col The column in the grid to place this component.
- * @param row The rw in the grid to place this component.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setCellX(int)
- * @see #setCellY(int)
- */
- public final CC cell(int col, int row)
- {
- setCellX(col);
- setCellY(row);
- return this;
- }
-
- /** Set the cell(s) that the component should occupy in the grid. Same functionality as {@link #setCellX(int col)} and
- * {@link #setCellY(int row)} together with {@link #setSpanX(int width)} and {@link #setSpanY(int height)}. This method
- * returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param col The column in the grid to place this component.
- * @param row The rw in the grid to place this component.
- * @param width How many cells the component should span (i.e. merge). <code>LayoutUtil.INF</code> spans to the end of the row.
- * @param height How many cells the component should span (i.e. merge). <code>LayoutUtil.INF</code> spans to the end of the column.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setCellX(int)
- * @see #setCellY(int)
- */
- public final CC cell(int col, int row, int width, int height)
- {
- setCellX(col);
- setCellY(row);
- setSpanX(width);
- setSpanY(height);
- return this;
- }
-
- /** Same functionality as <code>spanX(cellsX).spanY(cellsY)</code> which means this cell will span cells in both x and y.
- * This method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setSpanY(int)
- * @see #setSpanX(int)
- * @see #spanY()
- * @see #spanX()
- */
- public final CC span(int cellsX, int cellsY)
- {
- return spanX(cellsX).spanY(cellsY);
- }
-
- /** Same functionality as {@link #setSpanY(int LayoutUtil.INF)} which means this cell will span the rest of the column.
- * This method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setSpanY(int)
- * @see #spanY()
- */
- public final CC spanY()
- {
- return spanY(LayoutUtil.INF);
- }
-
- /** Same functionality as {@link #setSpanY(int cells)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param cells The number of cells to span (i.e. merge).
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setSpanY(int)
- */
- public final CC spanY(int cells)
- {
- setSpanY(cells);
- return this;
- }
-
- /** Same functionality as {@link #setSpanX(int LayoutUtil.INF)} which means this cell will span the rest of the row.
- * This method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setSpanX(int)
- * @see #spanX()
- */
- public final CC spanX()
- {
- return spanX(LayoutUtil.INF);
- }
-
- /** Same functionality as {@link #setSpanX(int cells)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param cells The number of cells to span (i.e. merge).
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setSpanY(int)
- */
- public final CC spanX(int cells)
- {
- setSpanX(cells);
- return this;
- }
-
- /** Same functionality as <code>pushX().pushY()</code> which means this cell will push in both x and y dimensions.
- * This method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setPushX(Float)
- * @see #setPushX(Float)
- * @see #pushY()
- * @see #pushX()
- */
- public final CC push()
- {
- return pushX().pushY();
- }
-
- /** Same functionality as <code>pushX(weightX).pushY(weightY)</code> which means this cell will push in both x and y dimensions.
- * This method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param weightX The weight used in the push.
- * @param weightY The weight used in the push.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setPushY(Float)
- * @see #setPushX(Float)
- * @see #pushY()
- * @see #pushX()
- */
- public final CC push(Float weightX, Float weightY)
- {
- return pushX(weightX).pushY(weightY);
- }
-
- /** Same functionality as {@link #setPushY(Float))} which means this cell will push the rest of the column.
- * This method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setPushY(Float)
- * @see #pushY()
- */
- public final CC pushY()
- {
- return pushY(ResizeConstraint.WEIGHT_100);
- }
-
- /** Same functionality as {@link #setPushY(Float weight)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param weight The weight used in the push.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setPushY(Float)
- */
- public final CC pushY(Float weight)
- {
- setPushY(weight);
- return this;
- }
-
- /** Same functionality as {@link #setPushX(Float)} which means this cell will push the rest of the row.
- * This method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setPushX(Float)
- * @see #pushX()
- */
- public final CC pushX()
- {
- return pushX(ResizeConstraint.WEIGHT_100);
- }
-
- /** Same functionality as {@link #setPushX(Float weight)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param weight The weight used in the push.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setPushY(Float)
- */
- public final CC pushX(Float weight)
- {
- setPushX(weight);
- return this;
- }
-
- /** Same functionality as {@link #setSplit(int parts)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param parts The number of parts (i.e. component slots) the cell should be divided into.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setSplit(int)
- */
- public final CC split(int parts)
- {
- setSplit(parts);
- return this;
- }
-
- /** Same functionality as {@link #setSkip(int)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param cells How many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setSkip(int)
- */
- public final CC skip(int cells)
- {
- setSkip(cells);
- return this;
- }
-
- /** Same functionality as {@link #setExternal(boolean true)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setExternal(boolean)
- */
- public final CC external()
- {
- setExternal(true);
- return this;
- }
-
- /** Same functionality as {@link #setFlowX(Boolean .TRUE)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setFlowX(Boolean)
- */
- public final CC flowX()
- {
- setFlowX(Boolean.TRUE);
- return this;
- }
-
- /** Same functionality as {@link #setFlowX(Boolean .FALSE)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setFlowX(Boolean)
- */
- public final CC flowY()
- {
- setFlowX(Boolean.FALSE);
- return this;
- }
-
-
- /** Same functionality as {@link #growX()} and {@link #growY()}.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #growX()
- * @see #growY()
- */
- public final CC grow()
- {
- growX();
- growY();
- return this;
- }
-
- /** Same functionality as {@link #setNewline(boolean true)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setNewline(boolean)
- */
- public final CC newline()
- {
- setNewline(true);
- return this;
- }
-
- /** Same functionality as {@link #setNewlineGapSize(BoundString)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param gapSize The gap size that will override the gap size in the row/colum constraints if <code>!= null</code>. E.g. "5px" or "unrel".
- * If <code>null</code> or <code>""</code> the newline size will be set to the default size and turned on. This is different compared to
- * {@link #setNewlineGapSize(BoundString)}.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setNewlineGapSize(BoundSize)
- */
- public final CC newline(String gapSize)
- {
- BoundSize bs = ConstraintParser.parseBoundSize(gapSize, true, (flowX != null && flowX == false));
- if (bs != null) {
- setNewlineGapSize(bs);
- } else {
- setNewline(true);
- }
- return this;
- }
-
- /** Same functionality as {@link #setWrap(boolean true)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setWrap(boolean)
- */
- public final CC wrap()
- {
- setWrap(true);
- return this;
- }
-
- /** Same functionality as {@link #setWrapGapSize(BoundString)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param gapSize The gap size that will override the gap size in the row/colum constraints if <code>!= null</code>. E.g. "5px" or "unrel".
- * If <code>null</code> or <code>""</code> the wrap size will be set to the default size and turned on. This is different compared to
- * {@link #setWrapGapSize(BoundString)}.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setWrapGapSize(BoundSize)
- */
- public final CC wrap(String gapSize)
- {
- BoundSize bs = ConstraintParser.parseBoundSize(gapSize, true, (flowX != null && flowX == false));
- if (bs != null) {
- setWrapGapSize(bs);
- } else {
- setWrap(true);
- }
- return this;
- }
-
- /** Same functionality as {@link #setDockSide(int 0)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setDockSide(int)
- */
- public final CC dockNorth()
- {
- setDockSide(0);
- return this;
- }
-
- /** Same functionality as {@link #setDockSide(int 1)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setDockSide(int)
- */
- public final CC dockWest()
- {
- setDockSide(1);
- return this;
- }
-
- /** Same functionality as {@link #setDockSide(int 2)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setDockSide(int)
- */
- public final CC dockSouth()
- {
- setDockSide(2);
- return this;
- }
-
- /** Same functionality as {@link #setDockSide(int 3)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setDockSide(int)
- */
- public final CC dockEast()
- {
- setDockSide(3);
- return this;
- }
-
- /** Sets the x-coordinate for the component. This is used to set the x coordinate position to a specific value. The component
- * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the x position.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setPos(UnitValue[])
- * @see #setBoundsInGrid(boolean)
- */
- public final CC x(String x)
- {
- return corrPos(x, 0);
- }
-
- /** Sets the y-coordinate for the component. This is used to set the y coordinate position to a specific value. The component
- * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the y position.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setPos(UnitValue[])
- * @see #setBoundsInGrid(boolean)
- */
- public final CC y(String y)
- {
- return corrPos(y, 1);
- }
-
- /** Sets the x2-coordinate for the component (right side). This is used to set the x2 coordinate position to a specific value. The component
- * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the x position.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param x2 The x2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setPos(UnitValue[])
- * @see #setBoundsInGrid(boolean)
- */
- public final CC x2(String x2)
- {
- return corrPos(x2, 2);
- }
-
- /** Sets the y2-coordinate for the component (bottom side). This is used to set the y2 coordinate position to a specific value. The component
- * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the y position.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param y2 The y2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setPos(UnitValue[])
- * @see #setBoundsInGrid(boolean)
- */
- public final CC y2(String y2)
- {
- return corrPos(y2, 3);
- }
-
- private final CC corrPos(String uv, int ix)
- {
- UnitValue[] b = getPos();
- if (b == null)
- b = new UnitValue[4];
-
- b[ix] = ConstraintParser.parseUnitValue(uv, (ix % 2 == 0));
- setPos(b);
-
- setBoundsInGrid(true);
- return this;
- }
-
- /** Same functionality as {@link #x(String x)} and {@link #y(String y)} toghether.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
- * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setPos(UnitValue[])
- */
- public final CC pos(String x, String y)
- {
- UnitValue[] b = getPos();
- if (b == null)
- b = new UnitValue[4];
-
- b[0] = ConstraintParser.parseUnitValue(x, true);
- b[1] = ConstraintParser.parseUnitValue(y, false);
- setPos(b);
-
- setBoundsInGrid(false);
- return this;
- }
-
- /** Same functionality as {@link #x(String x)}, {@link #y(String y)}, {@link #y2(String y)} and {@link #y2(String y)} toghether.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
- * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10".
- * @param x2 The x2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
- * @param y2 The y2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setPos(UnitValue[])
- */
- public final CC pos(String x, String y, String x2, String y2)
- {
- setPos(new UnitValue[] {
- ConstraintParser.parseUnitValue(x, true),
- ConstraintParser.parseUnitValue(y, false),
- ConstraintParser.parseUnitValue(x2, true),
- ConstraintParser.parseUnitValue(y2, false),
- });
- setBoundsInGrid(false);
- return this;
- }
-
- /** Same functionality as {@link #setPadding(UnitValue[])} but the unit values as absolute pixels. This method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param top The top padding that will be added to the y coordinate at the last stage in the layout.
- * @param left The top padding that will be added to the x coordinate at the last stage in the layout.
- * @param bottom The top padding that will be added to the y2 coordinate at the last stage in the layout.
- * @param right The top padding that will be added to the x2 coordinate at the last stage in the layout.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setTag(String)
- */
- public final CC pad(int top, int left, int bottom, int right)
- {
- setPadding(new UnitValue[] {
- new UnitValue(top), new UnitValue(left), new UnitValue(bottom), new UnitValue(right)
- });
- return this;
- }
-
- /** Same functionality as <code>setPadding(ConstraintParser.parseInsets(pad, false))}</code> only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param pad The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>.
- * @see #setTag(String)
- */
- public final CC pad(String pad)
- {
- setPadding(pad != null ? ConstraintParser.parseInsets(pad, false) : null);
- return this;
- }
-
- // **********************************************************
- // Bean properties
- // **********************************************************
-
- /** Returns the horizontal dimension constraint for this component constraint. It has constraints for the horizontal size
- * and grow/shink priorities and weights.
- * @return The current dimension constraint. Never <code>null</code>.
- */
- public DimConstraint getHorizontal()
- {
- return hor;
- }
-
- /** Sets the horizontal dimension constraint for this component constraint. It has constraints for the horizontal size
- * and grow/shink priorities and weights.
- * @param h The new dimension constraint. If <code>null</code> it will be reset to <code>new DimConstraint();</code>
- */
- public void setHorizontal(DimConstraint h)
- {
- hor = h != null ? h : new DimConstraint();
- }
-
- /** Returns the vertical dimension constraint for this component constraint. It has constraints for the vertical size
- * and grow/shink priorities and weights.
- * @return The current dimension constraint. Never <code>null</code>.
- */
- public DimConstraint getVertical()
- {
- return ver;
- }
-
- /** Sets the vertical dimension constraint for this component constraint. It has constraints for the vertical size
- * and grow/shink priorities and weights.
- * @param v The new dimension constraint. If <code>null</code> it will be reset to <code>new DimConstraint();</code>
- */
- public void setVertical(DimConstraint v)
- {
- ver = v != null ? v : new DimConstraint();
- }
-
- /** Returns the vertical or horizontal dim constraint.
- * @param isHor If the horizontal constraint should be returned.
- * @return The dim constraint. Never <code>null</code>.
- */
- public DimConstraint getDimConstraint(boolean isHor)
- {
- return isHor ? hor : ver;
- }
-
- /** Returns the absolute positioning of one or more of the edges. This will be applied last in the layout cycle and will not
- * affect the flow or grid positions. The positioning is relative to the parent and can not (as padding) be used
- * to adjust the edges relative to the old value. May be <code>null</code> and elements may be <code>null</code>.
- * <code>null</code> value(s) for the x2 and y2 will be interpreted as to keep the preferred size and thus the x1
- * and x2 will just absolutely positions the component.
- * <p>
- * Note that {@link #setBoundsInGrid(boolean)} changes the interpretation of thisproperty slightly.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value as a new array, free to modify.
- */
- public UnitValue[] getPos()
- {
- return pos != null ? new UnitValue[] {pos[0], pos[1], pos[2], pos[3]} : null;
- }
-
- /** Sets absolute positioning of one or more of the edges. This will be applied last in the layout cycle and will not
- * affect the flow or grid positions. The positioning is relative to the parent and can not (as padding) be used
- * to adjust the edges relative to the old value. May be <code>null</code> and elements may be <code>null</code>.
- * <code>null</code> value(s) for the x2 and y2 will be interpreted as to keep the preferred size and thus the x1
- * and x2 will just absolutely positions the component.
- * <p>
- * Note that {@link #setBoundsInGrid(boolean)} changes the interpretation of thisproperty slightly.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param pos <code>UnitValue[] {x, y, x2, y2}</code>. Must be <code>null</code> or of length 4. Elements can be <code>null</code>.
- */
- public void setPos(UnitValue[] pos)
- {
- this.pos = pos != null ? new UnitValue[] {pos[0], pos[1], pos[2], pos[3]} : null;
- }
-
- /** Returns if the absolute <code>pos</code> value should be corrections to the component that is in a normal cell. If <code>false</code>
- * the value of <code>pos</code> is truly absolute in that it will not affect the grid or have a default bounds in the grid.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- * @see #getPos()
- */
- public boolean isBoundsInGrid()
- {
- return boundsInGrid;
- }
-
- /** Sets if the absolute <code>pos</code> value should be corrections to the component that is in a normal cell. If <code>false</code>
- * the value of <code>pos</code> is truly absolute in that it will not affect the grid or have a default bounds in the grid.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param b <code>true</code> for bounds taken from the grid position. <code>false</code> is default.
- * @see #setPos(UnitValue[])
- */
- void setBoundsInGrid(boolean b)
- {
- this.boundsInGrid = b;
- }
-
- /** Returns the absolute cell position in the grid or <code>-1</code> if cell positioning is not used.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public int getCellX()
- {
- return cellX;
- }
-
- /** Set an absolute cell x-position in the grid. If >= 0 this point points to the absolute cell that this constaint's component should occupy.
- * If there's already a component in that cell they will split the cell. The flow will then continue after this cell.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param x The x-position or <code>-1</code> to disable cell positioning.
- */
- public void setCellX(int x)
- {
- cellX = x;
- }
-
- /** Returns the absolute cell position in the grid or <code>-1</code> if cell positioning is not used.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public int getCellY()
- {
- return cellX < 0 ? -1 : cellY;
- }
-
- /** Set an absolute cell x-position in the grid. If >= 0 this point points to the absolute cell that this constaint's component should occupy.
- * If there's already a component in that cell they will split the cell. The flow will then continue after this cell.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param y The y-position or <code>-1</code> to disable cell positioning.
- */
- public void setCellY(int y)
- {
- if (y < 0)
- cellX = -1;
- cellY = y < 0 ? 0 : y;
- }
-
- /** Sets the docking side. -1 means no docking.<br>
- * Valid sides are: <code> north = 0, west = 1, south = 2, east = 3</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current side.
- */
- public int getDockSide()
- {
- return dock;
- }
-
- /** Sets the docking side. -1 means no docking.<br>
- * Valid sides are: <code> north = 0, west = 1, south = 2, east = 3</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param side -1 or 0-3.
- */
- public void setDockSide(int side)
- {
- if (side < -1 || side > 3)
- throw new IllegalArgumentException("Illegal dock side: " + side);
- dock = side;
- }
-
- /** Returns if this component should have its bounds handled by an external source and not this layout manager.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public boolean isExternal()
- {
- return external;
- }
-
- /** If this boolean is true this component is not handled in any way by the layout manager and the component can have its bounds set by an external
- * handler which is normally by the use of some <code>component.setBounds(x, y, width, height)</code> directly (for Swing).
- * <p>
- * The bounds <b>will not</b> affect the minimum and preferred size of the container.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param b <code>true</code> means that the bounds are not changed.
- */
- public void setExternal(boolean b)
- {
- this.external = b;
- }
-
- /** Returns if the flow in the <b>cell</b> is in the horizontal dimension. Vertical if <code>false</code>. Only the first
- * component is a cell can set the flow.
- * <p>
- * If <code>null</code> the flow direction is inherited by from the {@link net.miginfocom.layout.LC}.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public Boolean getFlowX()
- {
- return flowX;
- }
-
- /** Sets if the flow in the <b>cell</b> is in the horizontal dimension. Vertical if <code>false</code>. Only the first
- * component is a cell can set the flow.
- * <p>
- * If <code>null</code> the flow direction is inherited by from the {@link net.miginfocom.layout.LC}.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param b <code>Boolean.TRUE</code> means horizontal flow in the cell.
- */
- public void setFlowX(Boolean b)
- {
- this.flowX = b;
- }
-
- /** Sets how a component that is hidden (not visible) should be treated by default.
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The mode:<br>
- * 0 == Normal. Bounds will be calculated as if the component was visible.<br>
- * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
- * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
- * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
- */
- public int getHideMode()
- {
- return hideMode;
- }
-
- /** Sets how a component that is hidden (not visible) should be treated by default.
- * @param mode The mode:<br>
- * 0 == Normal. Bounds will be calculated as if the component was visible.<br>
- * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
- * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
- * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
- */
- public void setHideMode(int mode)
- {
- if (mode < -1 || mode > 3)
- throw new IllegalArgumentException("Wrong hideMode: " + mode);
-
- hideMode = mode;
- }
-
- /** Returns the id used to reference this component in some constraints.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
- * The dot should never be first or last if present.
- */
- public String getId()
- {
- return id;
- }
-
- /** Sets the id used to reference this component in some constraints.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param id The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1".
- * The dot should never be first or last if present.
- */
- public void setId(String id)
- {
- this.id = id;
- }
-
- /** Returns the absolute resizing in the last stage of the layout cycle. May be <code>null</code> and elements may be <code>null</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value. <code>null</code> or of length 4.
- */
- public UnitValue[] getPadding()
- {
- return padding != null ? new UnitValue[] {padding[0], padding[1], padding[2], padding[3]} : null;
- }
-
- /** Sets the absolute resizing in the last stage of the layout cycle. These values are added to the edges and can thus for
- * instance be used to grow or reduce the size or move the component an absolute number of pixels. May be <code>null</code>
- * and elements may be <code>null</code>.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param sides top, left, bottom right. Must be <code>null</code> or of length 4.
- */
- public void setPadding(UnitValue[] sides)
- {
- this.padding = sides != null ? new UnitValue[] {sides[0], sides[1], sides[2], sides[3]} : null;
- }
-
- /** Returns how many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to.
- * <p>
- * Note that only the first component will be checked for this property.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value. 0 if no skip.
- */
- public int getSkip()
- {
- return skip;
- }
-
- /** Sets how many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to.
- * <p>
- * Note that only the first component will be checked for this property.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param cells How many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to
- */
- public void setSkip(int cells)
- {
- this.skip = cells;
- }
-
- /** Returns the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and
- * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row.
- * <p>
- * Note that only the first component will be checked for this property.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public int getSpanX()
- {
- return spanX;
- }
-
- /** Sets the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and
- * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row.
- * <p>
- * Note that only the first component will be checked for this property.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param cells The number of cells to span (i.e. merge).
- */
- public void setSpanX(int cells)
- {
- this.spanX = cells;
- }
-
- /** Returns the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and
- * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row.
- * <p>
- * Note that only the first component will be checked for this property.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public int getSpanY()
- {
- return spanY;
- }
-
- /** Sets the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and
- * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row.
- * <p>
- * Note that only the first component will be checked for this property.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param cells The number of cells to span (i.e. merge).
- */
- public void setSpanY(int cells)
- {
- this.spanY = cells;
- }
-
- /** "pushx" indicates that the column that this component is in (this first if the component spans) should default to growing.
- * If any other column has been set to grow this push value on the component does nothing as the column's explicit grow weight
- * will take precedence. Push is normally used when the grid has not been defined in the layout.
- * <p>
- * If multiple components in a column has push weights set the largest one will be used for the column.
- * @return The current push value. Default is <code>null</code>.
- */
- public Float getPushX()
- {
- return pushX;
- }
-
- /** "pushx" indicates that the column that this component is in (this first if the component spans) should default to growing.
- * If any other column has been set to grow this push value on the component does nothing as the column's explicit grow weight
- * will take precedence. Push is normally used when the grid has not been defined in the layout.
- * <p>
- * If multiple components in a column has push weights set the largest one will be used for the column.
- * @param weight The new push value. Default is <code>null</code>.
- */
- public void setPushX(Float weight)
- {
- this.pushX = weight;
- }
-
- /** "pushx" indicates that the row that this component is in (this first if the component spans) should default to growing.
- * If any other row has been set to grow this push value on the component does nothing as the row's explicit grow weight
- * will take precedence. Push is normally used when the grid has not been defined in the layout.
- * <p>
- * If multiple components in a row has push weights set the largest one will be used for the row.
- * @return The current push value. Default is <code>null</code>.
- */
- public Float getPushY()
- {
- return pushY;
- }
-
- /** "pushx" indicates that the row that this component is in (this first if the component spans) should default to growing.
- * If any other row has been set to grow this push value on the component does nothing as the row's explicit grow weight
- * will take precedence. Push is normally used when the grid has not been defined in the layout.
- * <p>
- * If multiple components in a row has push weights set the largest one will be used for the row.
- * @param weight The new push value. Default is <code>null</code>.
- */
- public void setPushY(Float weight)
- {
- this.pushY = weight;
- }
-
- /** Returns in how many parts the current cell (that this constraint's component will be in) should be split in. If for instance
- * it is split in two, the next componet will also share the same cell. Note that the cell can also span a number of
- * cells, which means that you can for instance span three cells and split that big cell for two components. Split can be
- * set to a very high value to make all components in the same row/column share the same cell (e.g. <code>LayoutUtil.INF</code>).
- * <p>
- * Note that only the first component will be checked for this property.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public int getSplit()
- {
- return split;
- }
-
- /** Sets in how many parts the current cell (that this constraint's component will be in) should be split in. If for instance
- * it is split in two, the next componet will also share the same cell. Note that the cell can also span a number of
- * cells, which means that you can for instance span three cells and split that big cell for two components. Split can be
- * set to a very high value to make all components in the same row/column share the same cell (e.g. <code>LayoutUtil.INF</code>).
- * <p>
- * Note that only the first component will be checked for this property.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param parts The number of parts (i.e. component slots) the cell should be divided into.
- */
- public void setSplit(int parts)
- {
- this.split = parts;
- }
-
- /** Tags the component with metadata. Currently only used to tag buttons with for instance "cancel" or "ok" to make them
- * show up in the correct order depending on platform. See {@link PlatformDefaults#setButtonOrder(String)} for information.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value. May be <code>null</code>.
- */
- public String getTag()
- {
- return tag;
- }
-
- /** Optinal tag that gives more context to this constraint's component. It is for instance used to tag buttons in a
- * button bar with the button type such as "ok", "help" or "cancel".
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param tag The new tag. May be <code>null</code>.
- */
- public void setTag(String tag)
- {
- this.tag = tag;
- }
-
- /** Returns if the flow should wrap to the next line/column <b>after</b> the component that this constraint belongs to.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public boolean isWrap()
- {
- return wrap != null;
- }
-
- /** Sets if the flow should wrap to the next line/column <b>after</b> the component that this constraint belongs to.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param b <code>true</code> means wrap after.
- */
- public void setWrap(boolean b)
- {
- wrap = b ? (wrap == null ? DEF_GAP : wrap) : null;
- }
-
- /** Returns the wrap size if it is a custom size. If wrap was set to true with {@link #setWrap(boolean)} then this method will
- * return <code>null</code> since that means that the gap size should be the default one as defined in the rows spec.
- * @return The custom gap size. NOTE! Will return <code>null</code> for both no wrap <b>and</b> default wrap.
- * @see #isWrap()
- * @see #setWrap(boolean)
- * @since 2.4.2
- */
- public BoundSize getWrapGapSize()
- {
- return wrap == DEF_GAP ? null : wrap;
- }
-
- /** Set the wrap size and turns wrap on if <code>!= null</code>.
- * @param s The custom gap size. NOTE! <code>null</code> will not turn on or off wrap, it will only set the wrap gap size to "default".
- * A non-null value will turn on wrap though.
- * @see #isWrap()
- * @see #setWrap(boolean)
- * @since 2.4.2
- */
- public void setWrapGapSize(BoundSize s)
- {
- wrap = s == null ? (wrap != null ? DEF_GAP : null) : s;
- }
-
- /** Returns if the flow should wrap to the next line/column <b>before</b> the component that this constraint belongs to.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current value.
- */
- public boolean isNewline()
- {
- return newline != null;
- }
-
- /** Sets if the flow should wrap to the next line/column <b>before</b> the component that this constraint belongs to.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param b <code>true</code> means wrap before.
- */
- public void setNewline(boolean b)
- {
- newline = b ? (newline == null ? DEF_GAP : newline) : null;
- }
-
- /** Returns the newline size if it is a custom size. If newline was set to true with {@link #setNewline(boolean)} then this method will
- * return <code>null</code> since that means that the gap size should be the default one as defined in the rows spec.
- * @return The custom gap size. NOTE! Will return <code>null</code> for both no newline <b>and</b> default newline.
- * @see #isNewline()
- * @see #setNewline(boolean)
- * @since 2.4.2
- */
- public BoundSize getNewlineGapSize()
- {
- return newline == DEF_GAP ? null : newline;
- }
-
- /** Set the newline size and turns newline on if <code>!= null</code>.
- * @param s The custom gap size. NOTE! <code>null</code> will not turn on or off newline, it will only set the newline gap size to "default".
- * A non-null value will turn on newline though.
- * @see #isNewline()
- * @see #setNewline(boolean)
- * @since 2.4.2
- */
- public void setNewlineGapSize(BoundSize s)
- {
- newline = s == null ? (newline != null ? DEF_GAP : null) : s;
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
-
- public void writeExternal(ObjectOutput out) throws IOException
- {
- if (getClass() == CC.class)
- LayoutUtil.writeAsXML(out, this);
- }
+package net.miginfocom.layout; + +import java.io.*; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** A simple value holder for one component's constraint. + */ +public final class CC implements Externalizable +{ + private static final BoundSize DEF_GAP = new BoundSize(null, null); // Only used to denote default wrap/newline gap. + + static final String[] DOCK_SIDES = {"north", "west", "south", "east"}; + + // See the getters and setters for information about the properties below. + + private int dock = -1; + + private UnitValue[] pos = null; // [x1, y1, x2, y2] + + private UnitValue[] padding = null; // top, left, bottom, right + + private Boolean flowX = null; + + private int skip = 0; + + private int split = 1; + + private int spanX = 1, spanY = 1; + + private int cellX = -1, cellY = 0; // If cellX is -1 then cellY is also considered -1. cellY is never negative. + + private String tag = null; + + private String id = null; + + private int hideMode = -1; + + private DimConstraint hor = new DimConstraint(); + + private DimConstraint ver = new DimConstraint(); + + private BoundSize newline = null; + + private BoundSize wrap = null; + + private boolean boundsInGrid = true; + + private boolean external = false; + + private Float pushX = null, pushY = null; + + + /** Empty constructor. + */ + public CC() + { + } + + // ********************************************************** + // Chaining constraint setters + // ********************************************************** + + /** Specifies that the component should be put in the end group <code>s</code> and will thus share the same ending + * coordinate as them within the group. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s A name to associate on the group that should be the same for other rows/columns in the same group. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC endGroupX(String s) + { + hor.setEndGroup(s); + return this; + } + + /** Specifies that the component should be put in the size group <code>s</code> and will thus share the same size + * as them within the group. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s A name to associate on the group that should be the same for other rows/columns in the same group. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC sizeGroupX(String s) + { + hor.setSizeGroup(s); + return this; + } + + /** The minimum size for the component. The value will override any value that is set on the component itself. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC minWidth(String size) + { + hor.setSize(LayoutUtil.derive(hor.getSize(), ConstraintParser.parseUnitValue(size, true), null, null)); + return this; + } + + /** The size for the component as a min and/or preferref and/or maximum size. The value will override any value that is set on + * the component itself. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The size expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC width(String size) + { + hor.setSize(ConstraintParser.parseBoundSize(size, false, true)); + return this; + } + + /** The maximum size for the component. The value will override any value that is set on the component itself. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC maxWidth(String size) + { + hor.setSize(LayoutUtil.derive(hor.getSize(), null, null, ConstraintParser.parseUnitValue(size, true))); + return this; + } + + + /** The horizontal gap before and/or after the component. The gap is towards cell bounds and/or other component bounds. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param before The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!". + * @param after The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC gapX(String before, String after) + { + if (before != null) + hor.setGapBefore(ConstraintParser.parseBoundSize(before, true, true)); + + if (after != null) + hor.setGapAfter(ConstraintParser.parseBoundSize(after, true, true)); + + return this; + } + + /** Same functionality as <code>getHorizontal().setAlign(ConstraintParser.parseUnitValue(unitValue, true))</code> only this method + * returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param align The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC alignX(String align) + { + hor.setAlign(ConstraintParser.parseUnitValueOrAlign(align, true, null)); + return this; + } + + /** The grow priority compared to other components in the same cell. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The grow priority. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC growPrioX(int p) + { + hor.setGrowPriority(p); + return this; + } + + /** Grow weight for the component horizontally. It default to weight <code>100</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #growX(float) + */ + public final CC growX() + { + hor.setGrow(ResizeConstraint.WEIGHT_100); + return this; + } + + /** Grow weight for the component horizontally. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param w The new grow weight. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC growX(float w) + { + hor.setGrow(new Float(w)); + return this; + } + + /** The shrink priority compared to other components in the same cell. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The shrink priority. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC shrinkPrioX(int p) + { + hor.setShrinkPriority(p); + return this; + } + + /** Shrink weight for the component horizontally. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param w The new shrink weight. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC shrinkX(float w) + { + hor.setShrink(new Float(w)); + return this; + } + + /** The end group that this componet should be placed in. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s The name of the group. If <code>null</code> that means no group (default) + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC endGroupY(String s) + { + ver.setEndGroup(s); + return this; + } + + /** The size group that this componet should be placed in. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s The name of the group. If <code>null</code> that means no group (default) + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC sizeGroupY(String s) + { + ver.setSizeGroup(s); + return this; + } + + /** The minimum size for the component. The value will override any value that is set on the component itself. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC minHeight(String size) + { + ver.setSize(LayoutUtil.derive(ver.getSize(), ConstraintParser.parseUnitValue(size, false), null, null)); + return this; + } + + /** The size for the component as a min and/or preferref and/or maximum size. The value will override any value that is set on + * the component itself. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The size expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC height(String size) + { + ver.setSize(ConstraintParser.parseBoundSize(size, false, false)); + return this; + } + + /** The maximum size for the component. The value will override any value that is set on the component itself. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The size expressed as a <code>UnitValue</code>. E.g. "100px" or "200mm". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC maxHeight(String size) + { + ver.setSize(LayoutUtil.derive(ver.getSize(), null, null, ConstraintParser.parseUnitValue(size, false))); + return this; + } + + /** The vertical gap before (normally above) and/or after (normally below) the component. The gap is towards cell bounds and/or other component bounds. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param before The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!". + * @param after The size of the gap expressed as a <code>BoundSize</code>. E.g. "50:100px:200mm" or "100px!". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC gapY(String before, String after) + { + if (before != null) + ver.setGapBefore(ConstraintParser.parseBoundSize(before, true, false)); + + if (after != null) + ver.setGapAfter(ConstraintParser.parseBoundSize(after, true, false)); + + return this; + } + + /** Same functionality as <code>getVertical().setAlign(ConstraintParser.parseUnitValue(unitValue, true))</code> only this method + * returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param align The align keyword or for instance "100px". E.g "top" or "bottom". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC alignY(String align) + { + ver.setAlign(ConstraintParser.parseUnitValueOrAlign(align, false, null)); + return this; + } + + /** The grow priority compared to other components in the same cell. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The grow priority. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC growPrioY(int p) + { + ver.setGrowPriority(p); + return this; + } + + /** Grow weight for the component vertically. Defaults to <code>100</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #growY(Float) + */ + public final CC growY() + { + ver.setGrow(ResizeConstraint.WEIGHT_100); + return this; + } + + /** Grow weight for the component vertically. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param w The new grow weight. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC growY(Float w) + { + ver.setGrow(w); + return this; + } + + /** The shrink priority compared to other components in the same cell. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The shrink priority. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC shrinkPrioY(int p) + { + ver.setShrinkPriority(p); + return this; + } + + /** Shrink weight for the component horizontally. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param w The new shrink weight. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC shrinkY(float w) + { + ver.setShrink(new Float(w)); + return this; + } + + /** How this component, if hidden (not visible), should be treated. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param mode The mode. Default to the mode in the {@link net.miginfocom.layout.LC}. + * 0 == Normal. Bounds will be calculated as if the component was visible.<br> + * 1 == If hidden the size will be 0, 0 but the gaps remain.<br> + * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br> + * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid.. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC hideMode(int mode) + { + setHideMode(mode); + return this; + } + + /** The id used to reference this component in some constraints. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1". + * The dot should never be first or last if present. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + */ + public final CC id(String s) + { + setId(s); + return this; + } + + /** Same functionality as {@link #setTag(String tag)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param tag The new tag. May be <code>null</code>. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setTag(String) + */ + public final CC tag(String tag) + { + setTag(tag); + return this; + } + + /** Same functionality as {@link #setCellX(int col)} and {@link #setCellY(int row)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param col The column in the grid to place this component. + * @param row The rw in the grid to place this component. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setCellX(int) + * @see #setCellY(int) + */ + public final CC cell(int col, int row) + { + setCellX(col); + setCellY(row); + return this; + } + + /** Set the cell(s) that the component should occupy in the grid. Same functionality as {@link #setCellX(int col)} and + * {@link #setCellY(int row)} together with {@link #setSpanX(int width)} and {@link #setSpanY(int height)}. This method + * returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param col The column in the grid to place this component. + * @param row The rw in the grid to place this component. + * @param width How many cells the component should span (i.e. merge). <code>LayoutUtil.INF</code> spans to the end of the row. + * @param height How many cells the component should span (i.e. merge). <code>LayoutUtil.INF</code> spans to the end of the column. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setCellX(int) + * @see #setCellY(int) + */ + public final CC cell(int col, int row, int width, int height) + { + setCellX(col); + setCellY(row); + setSpanX(width); + setSpanY(height); + return this; + } + + /** Same functionality as <code>spanX(cellsX).spanY(cellsY)</code> which means this cell will span cells in both x and y. + * This method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setSpanY(int) + * @see #setSpanX(int) + * @see #spanY() + * @see #spanX() + */ + public final CC span(int cellsX, int cellsY) + { + return spanX(cellsX).spanY(cellsY); + } + + /** Same functionality as {@link #setSpanY(int LayoutUtil.INF)} which means this cell will span the rest of the column. + * This method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setSpanY(int) + * @see #spanY() + */ + public final CC spanY() + { + return spanY(LayoutUtil.INF); + } + + /** Same functionality as {@link #setSpanY(int cells)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param cells The number of cells to span (i.e. merge). + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setSpanY(int) + */ + public final CC spanY(int cells) + { + setSpanY(cells); + return this; + } + + /** Same functionality as {@link #setSpanX(int LayoutUtil.INF)} which means this cell will span the rest of the row. + * This method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setSpanX(int) + * @see #spanX() + */ + public final CC spanX() + { + return spanX(LayoutUtil.INF); + } + + /** Same functionality as {@link #setSpanX(int cells)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param cells The number of cells to span (i.e. merge). + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setSpanY(int) + */ + public final CC spanX(int cells) + { + setSpanX(cells); + return this; + } + + /** Same functionality as <code>pushX().pushY()</code> which means this cell will push in both x and y dimensions. + * This method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setPushX(Float) + * @see #setPushX(Float) + * @see #pushY() + * @see #pushX() + */ + public final CC push() + { + return pushX().pushY(); + } + + /** Same functionality as <code>pushX(weightX).pushY(weightY)</code> which means this cell will push in both x and y dimensions. + * This method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param weightX The weight used in the push. + * @param weightY The weight used in the push. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setPushY(Float) + * @see #setPushX(Float) + * @see #pushY() + * @see #pushX() + */ + public final CC push(Float weightX, Float weightY) + { + return pushX(weightX).pushY(weightY); + } + + /** Same functionality as {@link #setPushY(Float))} which means this cell will push the rest of the column. + * This method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setPushY(Float) + * @see #pushY() + */ + public final CC pushY() + { + return pushY(ResizeConstraint.WEIGHT_100); + } + + /** Same functionality as {@link #setPushY(Float weight)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param weight The weight used in the push. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setPushY(Float) + */ + public final CC pushY(Float weight) + { + setPushY(weight); + return this; + } + + /** Same functionality as {@link #setPushX(Float)} which means this cell will push the rest of the row. + * This method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setPushX(Float) + * @see #pushX() + */ + public final CC pushX() + { + return pushX(ResizeConstraint.WEIGHT_100); + } + + /** Same functionality as {@link #setPushX(Float weight)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param weight The weight used in the push. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setPushY(Float) + */ + public final CC pushX(Float weight) + { + setPushX(weight); + return this; + } + + /** Same functionality as {@link #setSplit(int parts)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param parts The number of parts (i.e. component slots) the cell should be divided into. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setSplit(int) + */ + public final CC split(int parts) + { + setSplit(parts); + return this; + } + + /** Same functionality as {@link #setSkip(int)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param cells How many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setSkip(int) + */ + public final CC skip(int cells) + { + setSkip(cells); + return this; + } + + /** Same functionality as {@link #setExternal(boolean true)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setExternal(boolean) + */ + public final CC external() + { + setExternal(true); + return this; + } + + /** Same functionality as {@link #setFlowX(Boolean .TRUE)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setFlowX(Boolean) + */ + public final CC flowX() + { + setFlowX(Boolean.TRUE); + return this; + } + + /** Same functionality as {@link #setFlowX(Boolean .FALSE)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setFlowX(Boolean) + */ + public final CC flowY() + { + setFlowX(Boolean.FALSE); + return this; + } + + + /** Same functionality as {@link #growX()} and {@link #growY()}. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #growX() + * @see #growY() + */ + public final CC grow() + { + growX(); + growY(); + return this; + } + + /** Same functionality as {@link #setNewline(boolean true)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setNewline(boolean) + */ + public final CC newline() + { + setNewline(true); + return this; + } + + /** Same functionality as {@link #setNewlineGapSize(BoundString)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param gapSize The gap size that will override the gap size in the row/colum constraints if <code>!= null</code>. E.g. "5px" or "unrel". + * If <code>null</code> or <code>""</code> the newline size will be set to the default size and turned on. This is different compared to + * {@link #setNewlineGapSize(BoundString)}. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setNewlineGapSize(BoundSize) + */ + public final CC newline(String gapSize) + { + BoundSize bs = ConstraintParser.parseBoundSize(gapSize, true, (flowX != null && flowX == false)); + if (bs != null) { + setNewlineGapSize(bs); + } else { + setNewline(true); + } + return this; + } + + /** Same functionality as {@link #setWrap(boolean true)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setWrap(boolean) + */ + public final CC wrap() + { + setWrap(true); + return this; + } + + /** Same functionality as {@link #setWrapGapSize(BoundString)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param gapSize The gap size that will override the gap size in the row/colum constraints if <code>!= null</code>. E.g. "5px" or "unrel". + * If <code>null</code> or <code>""</code> the wrap size will be set to the default size and turned on. This is different compared to + * {@link #setWrapGapSize(BoundString)}. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setWrapGapSize(BoundSize) + */ + public final CC wrap(String gapSize) + { + BoundSize bs = ConstraintParser.parseBoundSize(gapSize, true, (flowX != null && flowX == false)); + if (bs != null) { + setWrapGapSize(bs); + } else { + setWrap(true); + } + return this; + } + + /** Same functionality as {@link #setDockSide(int 0)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setDockSide(int) + */ + public final CC dockNorth() + { + setDockSide(0); + return this; + } + + /** Same functionality as {@link #setDockSide(int 1)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setDockSide(int) + */ + public final CC dockWest() + { + setDockSide(1); + return this; + } + + /** Same functionality as {@link #setDockSide(int 2)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setDockSide(int) + */ + public final CC dockSouth() + { + setDockSide(2); + return this; + } + + /** Same functionality as {@link #setDockSide(int 3)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setDockSide(int) + */ + public final CC dockEast() + { + setDockSide(3); + return this; + } + + /** Sets the x-coordinate for the component. This is used to set the x coordinate position to a specific value. The component + * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the x position. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setPos(UnitValue[]) + * @see #setBoundsInGrid(boolean) + */ + public final CC x(String x) + { + return corrPos(x, 0); + } + + /** Sets the y-coordinate for the component. This is used to set the y coordinate position to a specific value. The component + * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the y position. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setPos(UnitValue[]) + * @see #setBoundsInGrid(boolean) + */ + public final CC y(String y) + { + return corrPos(y, 1); + } + + /** Sets the x2-coordinate for the component (right side). This is used to set the x2 coordinate position to a specific value. The component + * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the x position. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param x2 The x2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setPos(UnitValue[]) + * @see #setBoundsInGrid(boolean) + */ + public final CC x2(String x2) + { + return corrPos(x2, 2); + } + + /** Sets the y2-coordinate for the component (bottom side). This is used to set the y2 coordinate position to a specific value. The component + * bounds is still precalculated to the grid cell and this method should be seen as a way to correct the y position. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param y2 The y2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setPos(UnitValue[]) + * @see #setBoundsInGrid(boolean) + */ + public final CC y2(String y2) + { + return corrPos(y2, 3); + } + + private final CC corrPos(String uv, int ix) + { + UnitValue[] b = getPos(); + if (b == null) + b = new UnitValue[4]; + + b[ix] = ConstraintParser.parseUnitValue(uv, (ix % 2 == 0)); + setPos(b); + + setBoundsInGrid(true); + return this; + } + + /** Same functionality as {@link #x(String x)} and {@link #y(String y)} toghether. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10". + * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setPos(UnitValue[]) + */ + public final CC pos(String x, String y) + { + UnitValue[] b = getPos(); + if (b == null) + b = new UnitValue[4]; + + b[0] = ConstraintParser.parseUnitValue(x, true); + b[1] = ConstraintParser.parseUnitValue(y, false); + setPos(b); + + setBoundsInGrid(false); + return this; + } + + /** Same functionality as {@link #x(String x)}, {@link #y(String y)}, {@link #y2(String y)} and {@link #y2(String y)} toghether. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param x The x position as a UnitValue. E.g. "10" or "40mm" or "container.x+10". + * @param y The y position as a UnitValue. E.g. "10" or "40mm" or "container.x+10". + * @param x2 The x2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10". + * @param y2 The y2 side's position as a UnitValue. E.g. "10" or "40mm" or "container.x2 - 10". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setPos(UnitValue[]) + */ + public final CC pos(String x, String y, String x2, String y2) + { + setPos(new UnitValue[] { + ConstraintParser.parseUnitValue(x, true), + ConstraintParser.parseUnitValue(y, false), + ConstraintParser.parseUnitValue(x2, true), + ConstraintParser.parseUnitValue(y2, false), + }); + setBoundsInGrid(false); + return this; + } + + /** Same functionality as {@link #setPadding(UnitValue[])} but the unit values as absolute pixels. This method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param top The top padding that will be added to the y coordinate at the last stage in the layout. + * @param left The top padding that will be added to the x coordinate at the last stage in the layout. + * @param bottom The top padding that will be added to the y2 coordinate at the last stage in the layout. + * @param right The top padding that will be added to the x2 coordinate at the last stage in the layout. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setTag(String) + */ + public final CC pad(int top, int left, int bottom, int right) + { + setPadding(new UnitValue[] { + new UnitValue(top), new UnitValue(left), new UnitValue(bottom), new UnitValue(right) + }); + return this; + } + + /** Same functionality as <code>setPadding(ConstraintParser.parseInsets(pad, false))}</code> only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param pad The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new ComponentConstraint().noGrid().gap().fill()</code>. + * @see #setTag(String) + */ + public final CC pad(String pad) + { + setPadding(pad != null ? ConstraintParser.parseInsets(pad, false) : null); + return this; + } + + // ********************************************************** + // Bean properties + // ********************************************************** + + /** Returns the horizontal dimension constraint for this component constraint. It has constraints for the horizontal size + * and grow/shink priorities and weights. + * @return The current dimension constraint. Never <code>null</code>. + */ + public DimConstraint getHorizontal() + { + return hor; + } + + /** Sets the horizontal dimension constraint for this component constraint. It has constraints for the horizontal size + * and grow/shink priorities and weights. + * @param h The new dimension constraint. If <code>null</code> it will be reset to <code>new DimConstraint();</code> + */ + public void setHorizontal(DimConstraint h) + { + hor = h != null ? h : new DimConstraint(); + } + + /** Returns the vertical dimension constraint for this component constraint. It has constraints for the vertical size + * and grow/shink priorities and weights. + * @return The current dimension constraint. Never <code>null</code>. + */ + public DimConstraint getVertical() + { + return ver; + } + + /** Sets the vertical dimension constraint for this component constraint. It has constraints for the vertical size + * and grow/shink priorities and weights. + * @param v The new dimension constraint. If <code>null</code> it will be reset to <code>new DimConstraint();</code> + */ + public void setVertical(DimConstraint v) + { + ver = v != null ? v : new DimConstraint(); + } + + /** Returns the vertical or horizontal dim constraint. + * @param isHor If the horizontal constraint should be returned. + * @return The dim constraint. Never <code>null</code>. + */ + public DimConstraint getDimConstraint(boolean isHor) + { + return isHor ? hor : ver; + } + + /** Returns the absolute positioning of one or more of the edges. This will be applied last in the layout cycle and will not + * affect the flow or grid positions. The positioning is relative to the parent and can not (as padding) be used + * to adjust the edges relative to the old value. May be <code>null</code> and elements may be <code>null</code>. + * <code>null</code> value(s) for the x2 and y2 will be interpreted as to keep the preferred size and thus the x1 + * and x2 will just absolutely positions the component. + * <p> + * Note that {@link #setBoundsInGrid(boolean)} changes the interpretation of thisproperty slightly. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value as a new array, free to modify. + */ + public UnitValue[] getPos() + { + return pos != null ? new UnitValue[] {pos[0], pos[1], pos[2], pos[3]} : null; + } + + /** Sets absolute positioning of one or more of the edges. This will be applied last in the layout cycle and will not + * affect the flow or grid positions. The positioning is relative to the parent and can not (as padding) be used + * to adjust the edges relative to the old value. May be <code>null</code> and elements may be <code>null</code>. + * <code>null</code> value(s) for the x2 and y2 will be interpreted as to keep the preferred size and thus the x1 + * and x2 will just absolutely positions the component. + * <p> + * Note that {@link #setBoundsInGrid(boolean)} changes the interpretation of thisproperty slightly. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param pos <code>UnitValue[] {x, y, x2, y2}</code>. Must be <code>null</code> or of length 4. Elements can be <code>null</code>. + */ + public void setPos(UnitValue[] pos) + { + this.pos = pos != null ? new UnitValue[] {pos[0], pos[1], pos[2], pos[3]} : null; + } + + /** Returns if the absolute <code>pos</code> value should be corrections to the component that is in a normal cell. If <code>false</code> + * the value of <code>pos</code> is truly absolute in that it will not affect the grid or have a default bounds in the grid. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + * @see #getPos() + */ + public boolean isBoundsInGrid() + { + return boundsInGrid; + } + + /** Sets if the absolute <code>pos</code> value should be corrections to the component that is in a normal cell. If <code>false</code> + * the value of <code>pos</code> is truly absolute in that it will not affect the grid or have a default bounds in the grid. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param b <code>true</code> for bounds taken from the grid position. <code>false</code> is default. + * @see #setPos(UnitValue[]) + */ + void setBoundsInGrid(boolean b) + { + this.boundsInGrid = b; + } + + /** Returns the absolute cell position in the grid or <code>-1</code> if cell positioning is not used. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public int getCellX() + { + return cellX; + } + + /** Set an absolute cell x-position in the grid. If >= 0 this point points to the absolute cell that this constaint's component should occupy. + * If there's already a component in that cell they will split the cell. The flow will then continue after this cell. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param x The x-position or <code>-1</code> to disable cell positioning. + */ + public void setCellX(int x) + { + cellX = x; + } + + /** Returns the absolute cell position in the grid or <code>-1</code> if cell positioning is not used. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public int getCellY() + { + return cellX < 0 ? -1 : cellY; + } + + /** Set an absolute cell x-position in the grid. If >= 0 this point points to the absolute cell that this constaint's component should occupy. + * If there's already a component in that cell they will split the cell. The flow will then continue after this cell. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param y The y-position or <code>-1</code> to disable cell positioning. + */ + public void setCellY(int y) + { + if (y < 0) + cellX = -1; + cellY = y < 0 ? 0 : y; + } + + /** Sets the docking side. -1 means no docking.<br> + * Valid sides are: <code> north = 0, west = 1, south = 2, east = 3</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current side. + */ + public int getDockSide() + { + return dock; + } + + /** Sets the docking side. -1 means no docking.<br> + * Valid sides are: <code> north = 0, west = 1, south = 2, east = 3</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param side -1 or 0-3. + */ + public void setDockSide(int side) + { + if (side < -1 || side > 3) + throw new IllegalArgumentException("Illegal dock side: " + side); + dock = side; + } + + /** Returns if this component should have its bounds handled by an external source and not this layout manager. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public boolean isExternal() + { + return external; + } + + /** If this boolean is true this component is not handled in any way by the layout manager and the component can have its bounds set by an external + * handler which is normally by the use of some <code>component.setBounds(x, y, width, height)</code> directly (for Swing). + * <p> + * The bounds <b>will not</b> affect the minimum and preferred size of the container. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param b <code>true</code> means that the bounds are not changed. + */ + public void setExternal(boolean b) + { + this.external = b; + } + + /** Returns if the flow in the <b>cell</b> is in the horizontal dimension. Vertical if <code>false</code>. Only the first + * component is a cell can set the flow. + * <p> + * If <code>null</code> the flow direction is inherited by from the {@link net.miginfocom.layout.LC}. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public Boolean getFlowX() + { + return flowX; + } + + /** Sets if the flow in the <b>cell</b> is in the horizontal dimension. Vertical if <code>false</code>. Only the first + * component is a cell can set the flow. + * <p> + * If <code>null</code> the flow direction is inherited by from the {@link net.miginfocom.layout.LC}. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param b <code>Boolean.TRUE</code> means horizontal flow in the cell. + */ + public void setFlowX(Boolean b) + { + this.flowX = b; + } + + /** Sets how a component that is hidden (not visible) should be treated by default. + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The mode:<br> + * 0 == Normal. Bounds will be calculated as if the component was visible.<br> + * 1 == If hidden the size will be 0, 0 but the gaps remain.<br> + * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br> + * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid.. + */ + public int getHideMode() + { + return hideMode; + } + + /** Sets how a component that is hidden (not visible) should be treated by default. + * @param mode The mode:<br> + * 0 == Normal. Bounds will be calculated as if the component was visible.<br> + * 1 == If hidden the size will be 0, 0 but the gaps remain.<br> + * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br> + * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid.. + */ + public void setHideMode(int mode) + { + if (mode < -1 || mode > 3) + throw new IllegalArgumentException("Wrong hideMode: " + mode); + + hideMode = mode; + } + + /** Returns the id used to reference this component in some constraints. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1". + * The dot should never be first or last if present. + */ + public String getId() + { + return id; + } + + /** Sets the id used to reference this component in some constraints. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param id The id or <code>null</code>. May consist of a groupID and an componentID which are separated by a dot: ".". E.g. "grp1.id1". + * The dot should never be first or last if present. + */ + public void setId(String id) + { + this.id = id; + } + + /** Returns the absolute resizing in the last stage of the layout cycle. May be <code>null</code> and elements may be <code>null</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. <code>null</code> or of length 4. + */ + public UnitValue[] getPadding() + { + return padding != null ? new UnitValue[] {padding[0], padding[1], padding[2], padding[3]} : null; + } + + /** Sets the absolute resizing in the last stage of the layout cycle. These values are added to the edges and can thus for + * instance be used to grow or reduce the size or move the component an absolute number of pixels. May be <code>null</code> + * and elements may be <code>null</code>. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param sides top, left, bottom right. Must be <code>null</code> or of length 4. + */ + public void setPadding(UnitValue[] sides) + { + this.padding = sides != null ? new UnitValue[] {sides[0], sides[1], sides[2], sides[3]} : null; + } + + /** Returns how many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to. + * <p> + * Note that only the first component will be checked for this property. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. 0 if no skip. + */ + public int getSkip() + { + return skip; + } + + /** Sets how many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to. + * <p> + * Note that only the first component will be checked for this property. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param cells How many cells in the grid that should be skipped <b>before</b> the component that this constraint belongs to + */ + public void setSkip(int cells) + { + this.skip = cells; + } + + /** Returns the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and + * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row. + * <p> + * Note that only the first component will be checked for this property. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public int getSpanX() + { + return spanX; + } + + /** Sets the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and + * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row. + * <p> + * Note that only the first component will be checked for this property. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param cells The number of cells to span (i.e. merge). + */ + public void setSpanX(int cells) + { + this.spanX = cells; + } + + /** Returns the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and + * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row. + * <p> + * Note that only the first component will be checked for this property. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public int getSpanY() + { + return spanY; + } + + /** Sets the number of cells the cell that this constraint's component will span in the indicated dimension. <code>1</code> is default and + * means that it only spans the current cell. <code>LayoutUtil.INF</code> is used to indicate a span to the end of the column/row. + * <p> + * Note that only the first component will be checked for this property. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param cells The number of cells to span (i.e. merge). + */ + public void setSpanY(int cells) + { + this.spanY = cells; + } + + /** "pushx" indicates that the column that this component is in (this first if the component spans) should default to growing. + * If any other column has been set to grow this push value on the component does nothing as the column's explicit grow weight + * will take precedence. Push is normally used when the grid has not been defined in the layout. + * <p> + * If multiple components in a column has push weights set the largest one will be used for the column. + * @return The current push value. Default is <code>null</code>. + */ + public Float getPushX() + { + return pushX; + } + + /** "pushx" indicates that the column that this component is in (this first if the component spans) should default to growing. + * If any other column has been set to grow this push value on the component does nothing as the column's explicit grow weight + * will take precedence. Push is normally used when the grid has not been defined in the layout. + * <p> + * If multiple components in a column has push weights set the largest one will be used for the column. + * @param weight The new push value. Default is <code>null</code>. + */ + public void setPushX(Float weight) + { + this.pushX = weight; + } + + /** "pushx" indicates that the row that this component is in (this first if the component spans) should default to growing. + * If any other row has been set to grow this push value on the component does nothing as the row's explicit grow weight + * will take precedence. Push is normally used when the grid has not been defined in the layout. + * <p> + * If multiple components in a row has push weights set the largest one will be used for the row. + * @return The current push value. Default is <code>null</code>. + */ + public Float getPushY() + { + return pushY; + } + + /** "pushx" indicates that the row that this component is in (this first if the component spans) should default to growing. + * If any other row has been set to grow this push value on the component does nothing as the row's explicit grow weight + * will take precedence. Push is normally used when the grid has not been defined in the layout. + * <p> + * If multiple components in a row has push weights set the largest one will be used for the row. + * @param weight The new push value. Default is <code>null</code>. + */ + public void setPushY(Float weight) + { + this.pushY = weight; + } + + /** Returns in how many parts the current cell (that this constraint's component will be in) should be split in. If for instance + * it is split in two, the next componet will also share the same cell. Note that the cell can also span a number of + * cells, which means that you can for instance span three cells and split that big cell for two components. Split can be + * set to a very high value to make all components in the same row/column share the same cell (e.g. <code>LayoutUtil.INF</code>). + * <p> + * Note that only the first component will be checked for this property. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public int getSplit() + { + return split; + } + + /** Sets in how many parts the current cell (that this constraint's component will be in) should be split in. If for instance + * it is split in two, the next componet will also share the same cell. Note that the cell can also span a number of + * cells, which means that you can for instance span three cells and split that big cell for two components. Split can be + * set to a very high value to make all components in the same row/column share the same cell (e.g. <code>LayoutUtil.INF</code>). + * <p> + * Note that only the first component will be checked for this property. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param parts The number of parts (i.e. component slots) the cell should be divided into. + */ + public void setSplit(int parts) + { + this.split = parts; + } + + /** Tags the component with metadata. Currently only used to tag buttons with for instance "cancel" or "ok" to make them + * show up in the correct order depending on platform. See {@link PlatformDefaults#setButtonOrder(String)} for information. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. May be <code>null</code>. + */ + public String getTag() + { + return tag; + } + + /** Optinal tag that gives more context to this constraint's component. It is for instance used to tag buttons in a + * button bar with the button type such as "ok", "help" or "cancel". + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param tag The new tag. May be <code>null</code>. + */ + public void setTag(String tag) + { + this.tag = tag; + } + + /** Returns if the flow should wrap to the next line/column <b>after</b> the component that this constraint belongs to. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public boolean isWrap() + { + return wrap != null; + } + + /** Sets if the flow should wrap to the next line/column <b>after</b> the component that this constraint belongs to. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param b <code>true</code> means wrap after. + */ + public void setWrap(boolean b) + { + wrap = b ? (wrap == null ? DEF_GAP : wrap) : null; + } + + /** Returns the wrap size if it is a custom size. If wrap was set to true with {@link #setWrap(boolean)} then this method will + * return <code>null</code> since that means that the gap size should be the default one as defined in the rows spec. + * @return The custom gap size. NOTE! Will return <code>null</code> for both no wrap <b>and</b> default wrap. + * @see #isWrap() + * @see #setWrap(boolean) + * @since 2.4.2 + */ + public BoundSize getWrapGapSize() + { + return wrap == DEF_GAP ? null : wrap; + } + + /** Set the wrap size and turns wrap on if <code>!= null</code>. + * @param s The custom gap size. NOTE! <code>null</code> will not turn on or off wrap, it will only set the wrap gap size to "default". + * A non-null value will turn on wrap though. + * @see #isWrap() + * @see #setWrap(boolean) + * @since 2.4.2 + */ + public void setWrapGapSize(BoundSize s) + { + wrap = s == null ? (wrap != null ? DEF_GAP : null) : s; + } + + /** Returns if the flow should wrap to the next line/column <b>before</b> the component that this constraint belongs to. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current value. + */ + public boolean isNewline() + { + return newline != null; + } + + /** Sets if the flow should wrap to the next line/column <b>before</b> the component that this constraint belongs to. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param b <code>true</code> means wrap before. + */ + public void setNewline(boolean b) + { + newline = b ? (newline == null ? DEF_GAP : newline) : null; + } + + /** Returns the newline size if it is a custom size. If newline was set to true with {@link #setNewline(boolean)} then this method will + * return <code>null</code> since that means that the gap size should be the default one as defined in the rows spec. + * @return The custom gap size. NOTE! Will return <code>null</code> for both no newline <b>and</b> default newline. + * @see #isNewline() + * @see #setNewline(boolean) + * @since 2.4.2 + */ + public BoundSize getNewlineGapSize() + { + return newline == DEF_GAP ? null : newline; + } + + /** Set the newline size and turns newline on if <code>!= null</code>. + * @param s The custom gap size. NOTE! <code>null</code> will not turn on or off newline, it will only set the newline gap size to "default". + * A non-null value will turn on newline though. + * @see #isNewline() + * @see #setNewline(boolean) + * @since 2.4.2 + */ + public void setNewlineGapSize(BoundSize s) + { + newline = s == null ? (newline != null ? DEF_GAP : null) : s; + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + if (getClass() == CC.class) + LayoutUtil.writeAsXML(out, this); + } }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/layout/ComponentWrapper.java b/prototypes/miglayout/net/miginfocom/layout/ComponentWrapper.java index af96ca6b..d3180c1a 100644 --- a/prototypes/miglayout/net/miginfocom/layout/ComponentWrapper.java +++ b/prototypes/miglayout/net/miginfocom/layout/ComponentWrapper.java @@ -1,258 +1,258 @@ -package net.miginfocom.layout;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** A class that wraps the important parts of a Component.
- * <p>
- * <b>NOTE!</b>.equals() and .hashcode() should be shunted to the wrapped component. E.g.
- * <pre>
- * public int hashCode()
- {
- return getComponent().hashCode();
- }
-
- public final boolean equals(Object o)
- {
- if (o == null || o instanceof ComponentWrapper == false)
- return false;
-
- return getComponent().equals(((ComponentWrapper) o).getComponent());
- }
- * </pre>
- */
-public interface ComponentWrapper
-{
- static final int TYPE_UNSET = -1;
- public static final int TYPE_UNKNOWN = 0;
- public static final int TYPE_CONTAINER = 1;
- public static final int TYPE_LABEL = 2;
- public static final int TYPE_TEXT_FIELD = 3;
- public static final int TYPE_TEXT_AREA = 4;
- public static final int TYPE_BUTTON = 5;
- public static final int TYPE_LIST = 6;
- public static final int TYPE_TABLE = 7;
- public static final int TYPE_SCROLL_PANE = 8;
- public static final int TYPE_IMAGE = 9;
- public static final int TYPE_PANEL = 10;
- public static final int TYPE_COMBO_BOX = 11;
- public static final int TYPE_SLIDER = 12;
- public static final int TYPE_SPINNER = 13;
- public static final int TYPE_PROGRESS_BAR = 14;
- public static final int TYPE_TREE = 15;
- public static final int TYPE_CHECK_BOX = 16;
- public static final int TYPE_SCROLL_BAR = 17;
- public static final int TYPE_SEPARATOR = 18;
-
- /** Returns the actual object that this wrapper is aggregating. This might be needed for getting
- * information about the object that the wrapper interface does not provide.
- * <p>
- * If this is a container the container should be returned instead.
- * @return The actual object that this wrapper is aggregating. Not <code>null</code>.
- */
- public abstract Object getComponent();
-
- /** Returns the current x coordinate for this component.
- * @return The current x coordinate for this component.
- */
- public abstract int getX();
-
- /** Returns the current y coordinate for this component.
- * @return The current y coordinate for this component.
- */
- public abstract int getY();
-
- /** Returns the current width for this component.
- * @return The current width for this component.
- */
- public abstract int getWidth();
-
- /** Returns the current height for this component.
- * @return The current height for this component.
- */
- public abstract int getHeight();
-
- /** Returns the screen x-coordinate for the upper left coordinate of the component layoutable bounds.
- * @return The screen x-coordinate for the upper left coordinate of the component layoutable bounds.
- */
- public abstract int getScreenLocationX();
-
- /** Returns the screen y-coordinate for the upper left coordinate of the component layoutable bounds.
- * @return The screen y-coordinate for the upper left coordinate of the component layoutable bounds.
- */
- public abstract int getScreenLocationY();
-
- /** Returns the minimum width of the component.
- * @return The minimum width of the component.
- */
- public abstract int getMinimumWidth();
-
- /** Returns the minimum height of the component.
- * @return The minimum height of the component.
- */
- public abstract int getMinimumHeight();
-
- /** Returns the preferred width of the component.
- * @return The preferred width of the component.
- */
- public abstract int getPreferredWidth();
-
- /** Returns the preferred height of the component.
- * @return The preferred height of the component.
- */
- public abstract int getPreferredHeight();
-
- /** Returns the maximum width of the component.
- * @return The maximum width of the component.
- */
- public abstract int getMaximumWidth();
-
- /** Returns the maximum height of the component.
- * @return The maximum height of the component.
- */
- public abstract int getMaximumHeight();
-
- /** Sets the component's bounds.
- * @param x The x coordinate.
- * @param y The y coordinate.
- * @param width The width.
- * @param height The height.
- */
- public abstract void setBounds(int x, int y, int width, int height);
-
- /** Returns if the component's visibility is set to <code>true</code>. This should not return if the component is
- * actually visibile, but if the visibility is set to true or not.
- * @return <code>true</code> means visible.
- */
- public abstract boolean isVisible();
-
- /** Returns the baseline for the component given the suggested height.
- * @param width The width to calculate for if other than the current. If <code>-1</code> the current size should be used.
- * @param height The height to calculate for if other than the current. If <code>-1</code> the current size should be used.
- * @return The baseline from the top or -1 if not applicable.
- */
- public abstract int getBaseline(int width, int height);
-
- /** Returns if the component has a baseline and if it can be retrieved. Should for instance return
- * <code>false</code> for Swing before mustang.
- * @return If the component has a baseline and if it can be retrieved.
- */
- public abstract boolean hasBaseline();
-
- /** Returns the container for this component.
- * @return The container for this component. Should never be <code>null</code>.
- */
- public abstract ContainerWrapper getParent();
-
- /** Returns the pixel unit factor for the horizontal or vertical dimension.
- * <p>
- * The factor is 1 for both dimensions on the normal font in a JPanel on Windows. The factor should increase with a bigger "X".
- * <p>
- * This is the Swing version:
- * <pre>
- * Rectangle2D r = fm.getStringBounds("X", parent.getGraphics());
- * wFactor = r.getWidth() / 6;
- * hFactor = r.getHeight() / 13.27734375f;
- * </pre>
- * @param isHor If it is the horizontal factor that should be returned.
- * @return The factor.
- */
- public abstract float getPixelUnitFactor(boolean isHor);
-
- /** Returns the DPI (Dots Per Inch) of the screen the component is currently in or for the default
- * screen if the component is not visible.
- * @return The DPI.
- */
- public abstract int getHorizontalScreenDPI();
-
- /** Returns the DPI (Dots Per Inch) of the screen the component is currently in or for the default
- * screen if the component is not visible.
- * @return The DPI.
- */
- public abstract int getVerticalScreenDPI();
-
- /** Returns the pixel size of the screen that the component is currently in or for the default
- * screen if the component is not visible or <code>null</code>.
- * @return The screen size. E.g. <code>1280</code>.
- */
- public abstract int getScreenWidth();
-
- /** Returns the pixel size of the screen that the component is currently in or for the default
- * screen if the component is not visible or <code>null</code>.
- * @return The screen size. E.g. <code>1024</code>.
- */
- public abstract int getScreenHeight();
-
- /** Returns a String id that can be used to reference the component in link constraints. This value should
- * return the default id for the component. The id can be set for a component in the constraints and if
- * so the value returned by this method will never be used. If there are no sensible id for the component
- * <code>null</code> should be returned.
- * <p>
- * For instance the Swing implementation returns the string returned from <code>Component.getName()</code>.
- * @return The string link id or <code>null</code>.
- */
- public abstract String getLinkId();
-
- /** Returns a hash code that should be resonably different for anything that might change the layout. This value is used to
- * know if the component layout needs to clear any caches.
- * @return A hash code that should be resonably different for anything that might change the layout. Returns -1 if the widget is
- * disposed.
- */
- public abstract int getLayoutHashCode();
-
- /** Returns the padding on a component by component basis. This method can be overridden to return padding to compensate for example for
- * borders that have shadows or where the outer most pixel is not the visual "edge" to align to.
- * <p>
- * Default implementation returnes <code>null</code> for all components except for Windows XP's JTabbedPane which will return new Insets(0, 0, 2, 2).
- * <p>
- * <b>NOTE!</B> To reduce cenerated garbage the returned padding should never be changed so that the same insets can be returned many times.
- * @return <code>null</code> if no padding. <b>NOTE!</B> To reduce cenerated garbage the returned padding should never be changed so that
- * the same insets can be returned many times. [top, left, bottom, right]
- */
- public int[] getVisualPadding();
-
- /** Paints component outline to indicate where it is.
- */
- public abstract void paintDebugOutline();
-
- /** Returns the type of component that this wrapper is wrapping.
- * <p>
- * This method can be invoked often so the result should be cached.
- * @param disregardScrollPane Is <code>true</code> any wrapping scroll pane should be disregarded and the type
- * of the scrolled component should be returned.
- * @return The type of component that this wrapper is wrapping. E.g. {@link #TYPE_LABEL}.
- */
- public abstract int getComponetType(boolean disregardScrollPane);
-
- ;
+package net.miginfocom.layout; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** A class that wraps the important parts of a Component. + * <p> + * <b>NOTE!</b>.equals() and .hashcode() should be shunted to the wrapped component. E.g. + * <pre> + * public int hashCode() + { + return getComponent().hashCode(); + } + + public final boolean equals(Object o) + { + if (o == null || o instanceof ComponentWrapper == false) + return false; + + return getComponent().equals(((ComponentWrapper) o).getComponent()); + } + * </pre> + */ +public interface ComponentWrapper +{ + static final int TYPE_UNSET = -1; + public static final int TYPE_UNKNOWN = 0; + public static final int TYPE_CONTAINER = 1; + public static final int TYPE_LABEL = 2; + public static final int TYPE_TEXT_FIELD = 3; + public static final int TYPE_TEXT_AREA = 4; + public static final int TYPE_BUTTON = 5; + public static final int TYPE_LIST = 6; + public static final int TYPE_TABLE = 7; + public static final int TYPE_SCROLL_PANE = 8; + public static final int TYPE_IMAGE = 9; + public static final int TYPE_PANEL = 10; + public static final int TYPE_COMBO_BOX = 11; + public static final int TYPE_SLIDER = 12; + public static final int TYPE_SPINNER = 13; + public static final int TYPE_PROGRESS_BAR = 14; + public static final int TYPE_TREE = 15; + public static final int TYPE_CHECK_BOX = 16; + public static final int TYPE_SCROLL_BAR = 17; + public static final int TYPE_SEPARATOR = 18; + + /** Returns the actual object that this wrapper is aggregating. This might be needed for getting + * information about the object that the wrapper interface does not provide. + * <p> + * If this is a container the container should be returned instead. + * @return The actual object that this wrapper is aggregating. Not <code>null</code>. + */ + public abstract Object getComponent(); + + /** Returns the current x coordinate for this component. + * @return The current x coordinate for this component. + */ + public abstract int getX(); + + /** Returns the current y coordinate for this component. + * @return The current y coordinate for this component. + */ + public abstract int getY(); + + /** Returns the current width for this component. + * @return The current width for this component. + */ + public abstract int getWidth(); + + /** Returns the current height for this component. + * @return The current height for this component. + */ + public abstract int getHeight(); + + /** Returns the screen x-coordinate for the upper left coordinate of the component layoutable bounds. + * @return The screen x-coordinate for the upper left coordinate of the component layoutable bounds. + */ + public abstract int getScreenLocationX(); + + /** Returns the screen y-coordinate for the upper left coordinate of the component layoutable bounds. + * @return The screen y-coordinate for the upper left coordinate of the component layoutable bounds. + */ + public abstract int getScreenLocationY(); + + /** Returns the minimum width of the component. + * @return The minimum width of the component. + */ + public abstract int getMinimumWidth(); + + /** Returns the minimum height of the component. + * @return The minimum height of the component. + */ + public abstract int getMinimumHeight(); + + /** Returns the preferred width of the component. + * @return The preferred width of the component. + */ + public abstract int getPreferredWidth(); + + /** Returns the preferred height of the component. + * @return The preferred height of the component. + */ + public abstract int getPreferredHeight(); + + /** Returns the maximum width of the component. + * @return The maximum width of the component. + */ + public abstract int getMaximumWidth(); + + /** Returns the maximum height of the component. + * @return The maximum height of the component. + */ + public abstract int getMaximumHeight(); + + /** Sets the component's bounds. + * @param x The x coordinate. + * @param y The y coordinate. + * @param width The width. + * @param height The height. + */ + public abstract void setBounds(int x, int y, int width, int height); + + /** Returns if the component's visibility is set to <code>true</code>. This should not return if the component is + * actually visibile, but if the visibility is set to true or not. + * @return <code>true</code> means visible. + */ + public abstract boolean isVisible(); + + /** Returns the baseline for the component given the suggested height. + * @param width The width to calculate for if other than the current. If <code>-1</code> the current size should be used. + * @param height The height to calculate for if other than the current. If <code>-1</code> the current size should be used. + * @return The baseline from the top or -1 if not applicable. + */ + public abstract int getBaseline(int width, int height); + + /** Returns if the component has a baseline and if it can be retrieved. Should for instance return + * <code>false</code> for Swing before mustang. + * @return If the component has a baseline and if it can be retrieved. + */ + public abstract boolean hasBaseline(); + + /** Returns the container for this component. + * @return The container for this component. Should never be <code>null</code>. + */ + public abstract ContainerWrapper getParent(); + + /** Returns the pixel unit factor for the horizontal or vertical dimension. + * <p> + * The factor is 1 for both dimensions on the normal font in a JPanel on Windows. The factor should increase with a bigger "X". + * <p> + * This is the Swing version: + * <pre> + * Rectangle2D r = fm.getStringBounds("X", parent.getGraphics()); + * wFactor = r.getWidth() / 6; + * hFactor = r.getHeight() / 13.27734375f; + * </pre> + * @param isHor If it is the horizontal factor that should be returned. + * @return The factor. + */ + public abstract float getPixelUnitFactor(boolean isHor); + + /** Returns the DPI (Dots Per Inch) of the screen the component is currently in or for the default + * screen if the component is not visible. + * @return The DPI. + */ + public abstract int getHorizontalScreenDPI(); + + /** Returns the DPI (Dots Per Inch) of the screen the component is currently in or for the default + * screen if the component is not visible. + * @return The DPI. + */ + public abstract int getVerticalScreenDPI(); + + /** Returns the pixel size of the screen that the component is currently in or for the default + * screen if the component is not visible or <code>null</code>. + * @return The screen size. E.g. <code>1280</code>. + */ + public abstract int getScreenWidth(); + + /** Returns the pixel size of the screen that the component is currently in or for the default + * screen if the component is not visible or <code>null</code>. + * @return The screen size. E.g. <code>1024</code>. + */ + public abstract int getScreenHeight(); + + /** Returns a String id that can be used to reference the component in link constraints. This value should + * return the default id for the component. The id can be set for a component in the constraints and if + * so the value returned by this method will never be used. If there are no sensible id for the component + * <code>null</code> should be returned. + * <p> + * For instance the Swing implementation returns the string returned from <code>Component.getName()</code>. + * @return The string link id or <code>null</code>. + */ + public abstract String getLinkId(); + + /** Returns a hash code that should be resonably different for anything that might change the layout. This value is used to + * know if the component layout needs to clear any caches. + * @return A hash code that should be resonably different for anything that might change the layout. Returns -1 if the widget is + * disposed. + */ + public abstract int getLayoutHashCode(); + + /** Returns the padding on a component by component basis. This method can be overridden to return padding to compensate for example for + * borders that have shadows or where the outer most pixel is not the visual "edge" to align to. + * <p> + * Default implementation returnes <code>null</code> for all components except for Windows XP's JTabbedPane which will return new Insets(0, 0, 2, 2). + * <p> + * <b>NOTE!</B> To reduce cenerated garbage the returned padding should never be changed so that the same insets can be returned many times. + * @return <code>null</code> if no padding. <b>NOTE!</B> To reduce cenerated garbage the returned padding should never be changed so that + * the same insets can be returned many times. [top, left, bottom, right] + */ + public int[] getVisualPadding(); + + /** Paints component outline to indicate where it is. + */ + public abstract void paintDebugOutline(); + + /** Returns the type of component that this wrapper is wrapping. + * <p> + * This method can be invoked often so the result should be cached. + * @param disregardScrollPane Is <code>true</code> any wrapping scroll pane should be disregarded and the type + * of the scrolled component should be returned. + * @return The type of component that this wrapper is wrapping. E.g. {@link #TYPE_LABEL}. + */ + public abstract int getComponetType(boolean disregardScrollPane); + + ; }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/layout/ConstraintParser.java b/prototypes/miglayout/net/miginfocom/layout/ConstraintParser.java index 9abeafa7..7bea17d0 100644 --- a/prototypes/miglayout/net/miginfocom/layout/ConstraintParser.java +++ b/prototypes/miglayout/net/miginfocom/layout/ConstraintParser.java @@ -1,1409 +1,1409 @@ -package net.miginfocom.layout;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** Parses string constraints.
- */
-public final class ConstraintParser
-{
- private ConstraintParser()
- {
- }
-
- /** Parses the layout constraints and stores the parsed values in the transient (cache) member varables.
- * @param s The String to parse. Should not be <code>null</code> and <b>must be lower case and trimmed</b>.
- * @throws RuntimeException if the constaint was not valid.
- * @return The parsed constraint. Never <code>null</code>.
- */
- public static LC parseLayoutConstraint(String s)
- {
- LC lc = new LC();
- if (s.length() == 0)
- return lc;
-
- String[] parts = toTrimmedTokens(s, ',');
-
- // First check for "ltr" or "rtl" since that will affect the interpretation of the other constraints.
- for (int i = 0; i < parts.length; i++) {
- String part = parts[i];
- if (part == null)
- continue;
-
- int len = part.length();
- if (len == 3 || len == 11) { // Optimization
- if (part.equals("ltr") || part.equals("rtl") || part.equals("lefttoright") || part.equals("righttoleft")) {
- lc.setLeftToRight(part.charAt(0) == 'l' ? Boolean.TRUE : Boolean.FALSE);
- parts[i] = null; // So we will not try to interpret it again
- }
-
- if (part.equals("ttb") || part.equals("btt") || part.equals("toptobottom") || part.equals("bottomtotop")) {
- lc.setTopToBottom(part.charAt(0) == 't');
- parts[i] = null; // So we will not try to interpret it again
- }
- }
- }
-
- for (int i = 0; i < parts.length; i++) {
- String part = parts[i];
- if (part == null || part.length() == 0)
- continue;
-
- try {
- int ix = -1;
- char c = part.charAt(0);
-
- if (c == 'w') {
- ix = startsWithLenient(part, "wrap", -1, true);
- if (ix > -1) {
- String num = part.substring(ix).trim();
- lc.setWrapAfter(num.length() != 0 ? Integer.parseInt(num) : 0);
- continue;
- }
- }
-
- if (c == 'g') {
- if (part.startsWith("gapx ")) {
- lc.setGridGapX(parseBoundSize(part.substring(5).trim(), true, true));
- continue;
- }
-
- if (part.startsWith("gapy ")) {
- lc.setGridGapY(parseBoundSize(part.substring(5).trim(), true, false));
- continue;
- }
-
- if (part.startsWith("gap ")) {
- String[] gaps = toTrimmedTokens(part.substring(4).trim(), ' ');
- lc.setGridGapX(parseBoundSize(gaps[0], true, true));
- lc.setGridGapY(gaps.length > 1 ? parseBoundSize(gaps[1], true, false) : lc.getGridGapX());
- continue;
- }
- }
-
- if (c == 'd') {
- ix = startsWithLenient(part, "debug", 5, true);
- if (ix > -1) {
- String millis = part.substring(ix).trim();
- lc.setDebugMillis(millis.length() > 0 ? Integer.parseInt(millis) : 1000);
- continue;
- }
- }
-
- if (c == 'n') {
- if (part.equals("nogrid")) {
- lc.setNoGrid(true);
- continue;
- }
-
- if (part.equals("nocache")) {
- lc.setNoCache(true);
- continue;
- }
-
- if (part.equals("novisualpadding")) {
- lc.setVisualPadding(false);
- continue;
- }
- }
-
- if (c == 'f') {
- if (part.equals("fill") || part.equals("fillx") || part.equals("filly")) {
- lc.setFillX(part.length() == 4 || part.charAt(4) == 'x');
- lc.setFillY(part.length() == 4 || part.charAt(4) == 'y');
- continue;
- }
-
- if (part.equals("flowy")) {
- lc.setFlowX(false);
- continue;
- }
-
- if (part.equals("flowx")) {
- lc.setFlowX(true); // This is the default but added for consistency
- continue;
- }
- }
-
- if (c == 'i') {
- ix = startsWithLenient(part, "insets", 3, true);
- if (ix > -1) {
- String insStr = part.substring(ix).trim();
- UnitValue[] ins = parseInsets(insStr, true);
- LayoutUtil.putCCString(ins, insStr);
- lc.setInsets(ins);
- continue;
- }
- }
-
- if (c == 'a') {
- ix = startsWithLenient(part, new String[] {"aligny", "ay"}, new int[] {6, 2}, true);
- if (ix > -1) {
- lc.setAlignY(parseUnitValueOrAlign(part.substring(ix).trim(), false, null));
- continue;
- }
-
- ix = startsWithLenient(part, new String[] {"alignx", "ax"}, new int[] {6, 2}, true);
- if (ix > -1) {
- lc.setAlignX(parseUnitValueOrAlign(part.substring(ix).trim(), true, null));
- continue;
- }
-
- ix = startsWithLenient(part, "align", 2, true);
- if (ix > -1) {
- String[] gaps = toTrimmedTokens(part.substring(ix).trim(), ' ');
- lc.setAlignX(parseUnitValueOrAlign(gaps[0], true, null));
- lc.setAlignY(gaps.length > 1 ? parseUnitValueOrAlign(gaps[1], false, null) : lc.getAlignX());
- continue;
- }
- }
-
- if (c == 'h' && part.startsWith("hidemode ")) {
- lc.setHideMode(Integer.parseInt(part.substring(9)));
- continue;
- }
-
- if (lc.getAlignX() == null) {
- UnitValue alignX = parseAlignKeywords(part, true);
- if (alignX != null) {
- lc.setAlignX(alignX);
- continue;
- }
- }
-
- UnitValue alignY = parseAlignKeywords(part, false);
- if (alignY != null) {
- lc.setAlignY(alignY);
- continue;
- }
-
- throw new IllegalArgumentException("Unknown Constraint: '" + part + "'\n");
-
- } catch (Exception ex) {
- throw new IllegalArgumentException("Illegal Constraint: '" + part + "'\n" + ex.getMessage());
- }
- }
-
-// lc = (LC) serializeTest(lc);
-
- return lc;
- }
-
- /** Parses the column or rows constraints. They normally looks something like <code>"[min:pref]rel[10px][]"</code>.
- * @param s The string to parse. Not <code>null</code>.
- * @return An array of {@link DimConstraint}s that is as manu are there exist "[...]" sections in the string that is parsed.
- * @throws RuntimeException if the constaint was not valid.
- */
- public static AC parseRowConstraints(String s)
- {
- return parseAxisConstraint(s, false);
- }
-
- /** Parses the column or rows constraints. They normally looks something like <code>"[min:pref]rel[10px][]"</code>.
- * @param s The string to parse. Not <code>null</code>.
- * @return An array of {@link DimConstraint}s that is as manu are there exist "[...]" sections in the string that is parsed.
- * @throws RuntimeException if the constaint was not valid.
- */
- public static AC parseColumnConstraints(String s)
- {
- return parseAxisConstraint(s, true);
- }
-
- /** Parses the column or rows constraints. They normally looks something like <code>"[min:pref]rel[10px][]"</code>.
- * @param s The string to parse. Not <code>null</code>.
- * @param isCols If this for columns rather than rows.
- * @return An array of {@link DimConstraint}s that is as manu are there exist "[...]" sections in the string that is parsed.
- * @throws RuntimeException if the constaint was not valid.
- */
- private static AC parseAxisConstraint(String s, boolean isCols)
- {
- s = s.trim();
-
- if (s.length() == 0)
- return new AC(); // Short circuit for performance.
-
- s = s.toLowerCase();
-
- ArrayList<String> parts = getRowColAndGapsTrimmed(s);
-
- BoundSize[] gaps = new BoundSize[(parts.size() >> 1) + 1];
- for (int i = 0, iSz = parts.size(), gIx = 0; i < iSz; i += 2, gIx++)
- gaps[gIx] = parseBoundSize(parts.get(i), true, isCols);
-
- DimConstraint[] colSpecs = new DimConstraint[parts.size() >> 1];
- for (int i = 0, gIx = 0; i < colSpecs.length; i++, gIx++) {
- if (gIx >= gaps.length - 1)
- gIx = gaps.length - 2;
-
- colSpecs[i] = parseDimConstraint(parts.get((i << 1) + 1), gaps[gIx], gaps[gIx + 1], isCols);
- }
-
- AC ac = new AC();
- ac.setConstaints(colSpecs);
-
-// ac = (AC) serializeTest(ac);
-
- return ac;
- }
-
- /** Parses a single column or row constriant.
- * @param s The single constrint to parse. May look something like <code>"min:pref,fill,grow"</code>. Should not be <code>null</code> and <b>must
- * be lower case and trimmed</b>.
- * @param gapBefore The default gap "before" the column/row constraint. Can be overridden with a <code>"gap"</code> section within <code>s</code>.
- * @param gapAfter The default gap "after" the column/row constraint. Can be overridden with a <code>"gap"</code> section within <code>s</code>.
- * @param isCols If the constraints are column constraints rather than row constraints.
- * @return A single constraint. Never <code>null</code>.
- * @throws RuntimeException if the constaint was not valid.
- */
- private static DimConstraint parseDimConstraint(String s, BoundSize gapBefore, BoundSize gapAfter, boolean isCols)
- {
- DimConstraint dimConstraint = new DimConstraint();
-
- // Default values.
- dimConstraint.setGapBefore(gapBefore);
- dimConstraint.setGapAfter(gapAfter);
-
- String[] parts = toTrimmedTokens(s, ',');
- for (int i = 0; i < parts.length; i++) {
- String part = parts[i];
- try {
- if (part.length() == 0)
- continue;
-
- if (part.equals("fill")) {
- dimConstraint.setFill(true);
- dimConstraint.setAlign(null); // Can not have both fill and alignment
- continue;
- }
-
- if (part.equals("nogrid")) {
- dimConstraint.setNoGrid(true);
- continue;
- }
-
- int ix = -1;
- char c = part.charAt(0);
-
- if (c == 's') {
- ix = startsWithLenient(part, new String[] {"sizegroup", "sg"}, new int[] {5, 2}, true);
- if (ix > -1) {
- dimConstraint.setSizeGroup(part.substring(ix).trim());
- continue;
- }
-
-
- ix = startsWithLenient(part, new String[] {"shrinkprio", "shp"}, new int[] {10, 3}, true);
- if (ix > -1) {
- dimConstraint.setShrinkPriority(Integer.parseInt(part.substring(ix).trim()));
- continue;
- }
-
- ix = startsWithLenient(part, "shrink", 6, true);
- if (ix > -1) {
- dimConstraint.setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
- }
-
- if (c == 'g') {
- ix = startsWithLenient(part, new String[] {"growpriority", "gp"}, new int[] {5, 2}, true);
- if (ix > -1) {
- dimConstraint.setGrowPriority(Integer.parseInt(part.substring(ix).trim()));
- continue;
- }
-
- ix = startsWithLenient(part, "grow", 4, true);
- if (ix > -1) {
- dimConstraint.setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
- }
-
- if (c == 'a') {
- ix = startsWithLenient(part, "align", 2, true);
- if (ix > -1) {
- if (dimConstraint.isFill() == false) // Swallow, but ignore if fill is set.
- dimConstraint.setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), isCols, null));
- continue;
- }
- }
-
- UnitValue align = parseAlignKeywords(part, isCols);
- if (align != null) {
- if (dimConstraint.isFill() == false) // Swallow, but ignore if fill is set.
- dimConstraint.setAlign(align);
- continue;
- }
-
- // Only min:pref:max still left that is ok
- dimConstraint.setSize(parseBoundSize(part, false, isCols));
-
- } catch (Exception ex) {
- throw new IllegalArgumentException("Illegal contraint: '" + part + "'\n" + ex.getMessage());
- }
- }
- return dimConstraint;
- }
-
- /** Parses all component constraints and stores the parsed values in the transient (cache) member varables.
- * @param constrMap The constraints as <code>String</code>s. Strings <b>must be lower case and trimmed</b>
- * @return The parsed constraints. Never <code>null</code>.
- */
- public static Map<ComponentWrapper, CC> parseComponentConstraints(Map<ComponentWrapper, String> constrMap)
- {
- HashMap<ComponentWrapper, CC> flowConstrMap = new HashMap<ComponentWrapper, CC>();
-
- for (Iterator<Map.Entry<ComponentWrapper, String>> it = constrMap.entrySet().iterator(); it.hasNext();) {
- Map.Entry<ComponentWrapper, String> entry = it.next();
- flowConstrMap.put(entry.getKey(), parseComponentConstraint(entry.getValue()));
- }
-
- return flowConstrMap;
- }
-
- /** Parses one component constraint and returns the parsed value.
- * @param s The string to parse. Should not be <code>null</code> and <b>must be lower case and trimmed</b>.
- * @throws RuntimeException if the constaint was not valid.
- * @return The parsed constraint. Never <code>null</code>.
- */
- public static CC parseComponentConstraint(String s)
- {
- CC cc = new CC();
-
- if (s.length() == 0)
- return cc;
-
- String[] parts = toTrimmedTokens(s, ',');
-
- for (int i = 0; i < parts.length; i++) {
- String part = parts[i];
- try {
- if (part.length() == 0)
- continue;
-
- int ix = -1;
- char c = part.charAt(0);
-
- if (c == 'n') {
- if (part.equals("north")) {
- cc.setDockSide(0);
- continue;
- }
-
- if (part.equals("newline")) {
- cc.setNewline(true);
- continue;
- }
-
- if (part.startsWith("newline ")) {
- String gapSz = part.substring(7).trim();
- cc.setNewlineGapSize(parseBoundSize(gapSz, true, true));
- continue;
- }
- }
-
- if (c == 'f' && (part.equals("flowy") || part.equals("flowx"))) {
- cc.setFlowX(part.charAt(4) == 'x' ? Boolean.TRUE : Boolean.FALSE);
- continue;
- }
-
- if (c == 's') {
- ix = startsWithLenient(part, "skip", 4, true);
- if (ix > -1) {
- String num = part.substring(ix).trim();
- cc.setSkip(num.length() != 0 ? Integer.parseInt(num) : 1);
- continue;
- }
-
- ix = startsWithLenient(part, "split", 5, true);
- if (ix > -1) {
- String split = part.substring(ix).trim();
- cc.setSplit(split.length() > 0 ? Integer.parseInt(split) : LayoutUtil.INF);
- continue;
- }
-
- if (part.equals("south")) {
- cc.setDockSide(2);
- continue;
- }
-
- ix = startsWithLenient(part, new String[] {"spany","sy"}, new int[] {5, 2}, true);
- if (ix > -1) {
- cc.setSpanY(parseSpan(part.substring(ix).trim()));
- continue;
- }
-
- ix = startsWithLenient(part, new String[] {"spanx","sx"}, new int[] {5, 2}, true);
- if (ix > -1) {
- cc.setSpanX(parseSpan(part.substring(ix).trim()));
- continue;
- }
-
- ix = startsWithLenient(part, "span", 4, true);
- if (ix > -1) {
- String[] spans = toTrimmedTokens(part.substring(ix).trim(), ' ');
- cc.setSpanX(spans[0].length() > 0 ? Integer.parseInt(spans[0]) : LayoutUtil.INF);
- cc.setSpanY(spans.length > 1 ? Integer.parseInt(spans[1]) : 1);
- continue;
- }
-
- ix = startsWithLenient(part, "shrinkx", 7, true);
- if (ix > -1) {
- cc.getHorizontal().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
-
- ix = startsWithLenient(part, "shrinky", 7, true);
- if (ix > -1) {
- cc.getVertical().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
-
- ix = startsWithLenient(part, "shrink", 6, false);
- if (ix > -1) {
- String[] shrinks = toTrimmedTokens(part.substring(ix).trim(), ' ');
- cc.getHorizontal().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- if (shrinks.length > 1)
- cc.getVertical().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
-
- ix = startsWithLenient(part, new String[] {"shrinkprio", "shp"}, new int[] {10, 3}, true);
- if (ix > -1) {
- String sp = part.substring(ix).trim();
- if (sp.startsWith("x") || sp.startsWith("y")) { // To gandle "gpx", "gpy", "shrinkpriorityx", shrinkpriorityy"
- (sp.startsWith("x") ? cc.getHorizontal() : cc.getVertical()).setShrinkPriority(Integer.parseInt(sp.substring(2)));
- } else {
- String[] shrinks = toTrimmedTokens(sp, ' ');
- cc.getHorizontal().setShrinkPriority(Integer.parseInt(shrinks[0]));
- if (shrinks.length > 1)
- cc.getVertical().setShrinkPriority(Integer.parseInt(shrinks[1]));
- }
- continue;
- }
-
- ix = startsWithLenient(part, new String[] {"sizegroupx", "sizegroupy", "sgx", "sgy"}, new int[] {9, 9, 2, 2}, true);
- if (ix > -1) {
- String sg = part.substring(ix).trim();
- char lc = part.charAt(ix - 1);
- if (lc != 'y')
- cc.getHorizontal().setSizeGroup(sg);
- if (lc != 'x')
- cc.getVertical().setSizeGroup(sg);
- continue;
- }
- }
-
- if (c == 'g') {
- ix = startsWithLenient(part, "growx", 5, true);
- if (ix > -1) {
- cc.getHorizontal().setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
-
- ix = startsWithLenient(part, "growy", 5, true);
- if (ix > -1) {
- cc.getVertical().setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
-
- ix = startsWithLenient(part, "grow", 4, false);
- if (ix > -1) {
- String[] grows = toTrimmedTokens(part.substring(ix).trim(), ' ');
- cc.getHorizontal().setGrow(parseFloat(grows[0], ResizeConstraint.WEIGHT_100));
- cc.getVertical().setGrow(parseFloat(grows.length > 1 ? grows[1] : "", ResizeConstraint.WEIGHT_100));
- continue;
- }
-
- ix = startsWithLenient(part, new String[] {"growprio", "gp"}, new int[] {8, 2}, true);
- if (ix > -1) {
- String gp = part.substring(ix).trim();
- char c0 = gp.length() > 0 ? gp.charAt(0) : ' ';
- if (c0 == 'x' || c0 == 'y') { // To gandle "gpx", "gpy", "growpriorityx", growpriorityy"
- (c0 == 'x' ? cc.getHorizontal() : cc.getVertical()).setGrowPriority(Integer.parseInt(gp.substring(2)));
- } else {
- String[] grows = toTrimmedTokens(gp, ' ');
- cc.getHorizontal().setGrowPriority(Integer.parseInt(grows[0]));
- if (grows.length > 1)
- cc.getVertical().setGrowPriority(Integer.parseInt(grows[1]));
- }
- continue;
- }
-
- if (part.startsWith("gap")) {
- BoundSize[] gaps = parseGaps(part);
- if (gaps[0] != null)
- cc.getVertical().setGapBefore(gaps[0]);
- if (gaps[1] != null)
- cc.getHorizontal().setGapBefore(gaps[1]);
- if (gaps[2] != null)
- cc.getVertical().setGapAfter(gaps[2]);
- if (gaps[3] != null)
- cc.getHorizontal().setGapAfter(gaps[3]);
- continue;
- }
- }
-
- if (c == 'a') {
- ix = startsWithLenient(part, new String[] {"aligny", "ay"}, new int[] {6, 2}, true);
- if (ix > -1) {
- cc.getVertical().setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), false, null));
- continue;
- }
-
- ix = startsWithLenient(part, new String[] {"alignx", "ax"}, new int[] {6, 2}, true);
- if (ix > -1) {
- cc.getHorizontal().setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), true, null));
- continue;
- }
-
- ix = startsWithLenient(part, "align", 2, true);
- if (ix > -1) {
- String[] gaps = toTrimmedTokens(part.substring(ix).trim(), ' ');
- cc.getHorizontal().setAlign(parseUnitValueOrAlign(gaps[0], true, null));
- if (gaps.length > 1)
- cc.getVertical().setAlign(parseUnitValueOrAlign(gaps[1], false, null));
- continue;
- }
- }
-
- if ((c == 'x' || c == 'y') && part.length() > 2) {
- char c2 = part.charAt(1);
- if (c2 == ' ' || (c2 == '2' && part.charAt(2) == ' ')) {
- if (cc.getPos() == null) {
- cc.setPos(new UnitValue[4]);
- } else if (cc.isBoundsInGrid() == false) {
- throw new IllegalArgumentException("Can not combine 'position' with 'x/y/x2/y2' keywords.");
- }
-
- int edge = (c == 'x' ? 0 : 1) + (c2 == '2' ? 2 : 0);
- UnitValue[] pos = cc.getPos();
- pos[edge] = parseUnitValue(part.substring(2).trim(), null, c == 'x');
- cc.setPos(pos);
- cc.setBoundsInGrid(true);
- continue;
- }
- }
-
- if (c == 'c') {
- ix = startsWithLenient(part, "cell", 4, true);
- if (ix > -1) {
- String[] grs = toTrimmedTokens(part.substring(ix).trim(), ' ');
- if (grs.length < 2)
- throw new IllegalArgumentException("At least two integers must follow " + part);
- cc.setCellX(Integer.parseInt(grs[0]));
- cc.setCellY(Integer.parseInt(grs[1]));
- if (grs.length > 2)
- cc.setSpanX(Integer.parseInt(grs[2]));
- if (grs.length > 3)
- cc.setSpanY(Integer.parseInt(grs[3]));
- continue;
- }
- }
-
- if (c == 'p') {
- ix = startsWithLenient(part, "pos", 3, true);
- if (ix > -1) {
- if (cc.getPos() != null && cc.isBoundsInGrid())
- throw new IllegalArgumentException("Can not combine 'pos' with 'x/y/x2/y2' keywords.");
-
- String[] pos = toTrimmedTokens(part.substring(ix).trim(), ' ');
- UnitValue[] bounds = new UnitValue[4];
- for (int j = 0; j < pos.length; j++)
- bounds[j] = parseUnitValue(pos[j], null, j % 2 == 0);
-
- if (bounds[0] == null && bounds[2] == null || bounds[1] == null && bounds[3] == null)
- throw new IllegalArgumentException("Both x and x2 or y and y2 can not be null!");
-
- cc.setPos(bounds);
- cc.setBoundsInGrid(false);
- continue;
- }
-
- ix = startsWithLenient(part, "pad", 3, true);
- if (ix > -1) {
- UnitValue[] p = parseInsets(part.substring(ix).trim(), false);
- cc.setPadding(new UnitValue[] {
- p[0],
- p.length > 1 ? p[1] : null,
- p.length > 2 ? p[2] : null,
- p.length > 3 ? p[3] : null});
- continue;
- }
-
- ix = startsWithLenient(part, "pushx", 5, true);
- if (ix > -1) {
- cc.setPushX(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
-
- ix = startsWithLenient(part, "pushy", 5, true);
- if (ix > -1) {
- cc.setPushY(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100));
- continue;
- }
-
- ix = startsWithLenient(part, "push", 4, false);
- if (ix > -1) {
- String[] pushs = toTrimmedTokens(part.substring(ix).trim(), ' ');
- cc.setPushX(parseFloat(pushs[0], ResizeConstraint.WEIGHT_100));
- cc.setPushY(parseFloat(pushs.length > 1 ? pushs[1] : "", ResizeConstraint.WEIGHT_100));
- continue;
- }
- }
-
- if (c == 't') {
- ix = startsWithLenient(part, "tag", 3, true);
- if (ix > -1) {
- cc.setTag(part.substring(ix).trim());
- continue;
- }
- }
-
- if (c == 'w' || c == 'h') {
- if (part.equals("wrap")) {
- cc.setWrap(true);
- continue;
- }
-
- if (part.startsWith("wrap ")) {
- String gapSz = part.substring(5).trim();
- cc.setWrapGapSize(parseBoundSize(gapSz, true, true));
- continue;
- }
-
- boolean isHor = c == 'w';
- if (isHor && (part.startsWith("w ") || part.startsWith("width "))) {
- String uvStr = part.substring(part.charAt(1) == ' ' ? 2 : 6).trim();
- BoundSize wbs = parseBoundSize(uvStr, false, true);
- LayoutUtil.putCCString(wbs, uvStr);
- cc.getHorizontal().setSize(wbs);
- continue;
- }
-
- if (!isHor && (part.startsWith("h ") || part.startsWith("height "))) {
- String uvStr = part.substring(part.charAt(1) == ' ' ? 2 : 7).trim();
- BoundSize hbs = parseBoundSize(uvStr, false, false);
- LayoutUtil.putCCString(hbs, uvStr);
- cc.getVertical().setSize(hbs);
- continue;
- }
-
- if (part.startsWith("wmin ") || part.startsWith("wmax ") || part.startsWith("hmin ") || part.startsWith("hmax ")) {
- String uvStr = part.substring(5).trim();
- if (uvStr.length() > 0) {
- UnitValue uv = parseUnitValue(uvStr, null, isHor);
- boolean isMin = part.charAt(3) == 'n';
- DimConstraint dc = isHor ? cc.getHorizontal() : cc.getVertical();
- dc.setSize(new BoundSize(
- isMin ? uv : (dc.getSize() != null ? dc.getSize().getMin() : null),
- dc.getSize() != null ? dc.getSize().getPreferred() : null,
- isMin ? (dc.getSize() != null ? dc.getSize().getMax() : null) : uv,
- uvStr
- ));
- continue;
- }
- }
-
- if (part.equals("west")) {
- cc.setDockSide(1);
-// cc.getVertical().setGrow(ResizeConstraint.WEIGHT_100);
- continue;
- }
-
- if (part.startsWith("hidemode ")) {
- cc.setHideMode(Integer.parseInt(part.substring(9)));
- continue;
- }
- }
-
- if (c == 'i' && part.startsWith("id ")) {
- cc.setId(part.substring(3).trim());
- int dIx = cc.getId().indexOf('.');
- if (dIx == 0 || dIx == cc.getId().length() - 1)
- throw new IllegalArgumentException("Dot must not be first or last!");
-
- continue;
- }
-
- if (c == 'e') {
- if (part.equals("east")) {
- cc.setDockSide(3);
-// cc.getVertical().setGrow(ResizeConstraint.WEIGHT_100);
- continue;
- }
-
- if (part.equals("external")) {
- cc.setExternal(true);
- continue;
- }
-
- ix = startsWithLenient(part, new String[] {"endgroupx", "endgroupy", "egx", "egy"}, new int[] {-1, -1, -1, -1}, true);
- if (ix > -1) {
- String sg = part.substring(ix).trim();
- char lc = part.charAt(ix - 1);
- DimConstraint dc = (lc == 'x' ? cc.getHorizontal() : cc.getVertical());
- dc.setEndGroup(sg);
- continue;
- }
- }
-
- if (c == 'd') {
- if (part.equals("dock north")) {
- cc.setDockSide(0);
- continue;
- }
- if (part.equals("dock west")) {
- cc.setDockSide(1);
- continue;
- }
- if (part.equals("dock south")) {
- cc.setDockSide(2);
- continue;
- }
- if (part.equals("dock east")) {
- cc.setDockSide(3);
- continue;
- }
-
- if (part.equals("dock center")) {
- cc.getHorizontal().setGrow(new Float(100f));
- cc.getVertical().setGrow(new Float(100f));
- continue;
- }
- }
-
- UnitValue horAlign = parseAlignKeywords(part, true);
- if (horAlign != null) {
- cc.getHorizontal().setAlign(horAlign);
- continue;
- }
-
- UnitValue verAlign = parseAlignKeywords(part, false);
- if (verAlign != null) {
- cc.getVertical().setAlign(verAlign);
- continue;
- }
-
- throw new IllegalArgumentException("Unknown keyword.");
-
- } catch (Exception ex) {
- throw new IllegalArgumentException("Illegal Constraint: '" + part + "'\n" + ex.getMessage());
- }
- }
-
-// cc = (CC) serializeTest(cc);
-
- return cc;
- }
-
- /** Parses insets which consists of 1-4 <code>UnitValue</code>s.
- * @param s The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing.
- * @param acceptPanel If "panel" and "dialog" should be accepted. They are used to access platform defaults.
- * @return An array of length 4 with the parsed insets.
- * @throws IllegalArgumentException if the parsing could not be done.
- */
- public static UnitValue[] parseInsets(String s, boolean acceptPanel)
- {
- if (s.length() == 0 || s.equals("dialog") || s.equals("panel")) {
- if (acceptPanel == false)
- throw new IllegalAccessError("Insets now allowed: " + s + "\n");
-
- boolean isPanel = s.startsWith("p");
- UnitValue[] ins = new UnitValue[4];
- for (int j = 0; j < 4; j++)
- ins[j] = isPanel ? PlatformDefaults.getPanelInsets(j) : PlatformDefaults.getDialogInsets(j);
-
- return ins;
- } else {
- String[] insS = toTrimmedTokens(s, ' ');
- UnitValue[] ins = new UnitValue[4];
- for (int j = 0; j < 4; j++) {
- UnitValue insSz = parseUnitValue(insS[j < insS.length ? j : insS.length - 1], UnitValue.ZERO, j % 2 == 1);
- ins[j] = insSz != null ? insSz : PlatformDefaults.getPanelInsets(j);
- }
- return ins;
- }
- }
-
- /** Parses gaps.
- * @param s The string that contains gap information. Should start with "gap".
- * @return The gaps as specified in <code>s</code>. Indexed: <code>[top,left,bottom,right][min,pref,max]</code> or
- * [before,after][min,pref,max] if <code>oneDim</code> is true.
- */
- private static BoundSize[] parseGaps(String s)
- {
- BoundSize[] ret = new BoundSize[4];
-
- int ix = startsWithLenient(s, "gaptop", -1, true);
- if (ix > -1) {
- s = s.substring(ix).trim();
- ret[0] = parseBoundSize(s, true, false);
- return ret;
- }
-
- ix = startsWithLenient(s, "gapleft", -1, true);
- if (ix > -1) {
- s = s.substring(ix).trim();
- ret[1] = parseBoundSize(s, true, true);
- return ret;
- }
-
- ix = startsWithLenient(s, "gapbottom", -1, true);
- if (ix > -1) {
- s = s.substring(ix).trim();
- ret[2] = parseBoundSize(s, true, false);
- return ret;
- }
-
- ix = startsWithLenient(s, "gapright", -1, true);
- if (ix > -1) {
- s = s.substring(ix).trim();
- ret[3] = parseBoundSize(s, true, true);
- return ret;
- }
-
- ix = startsWithLenient(s, "gapbefore", -1, true);
- if (ix > -1) {
- s = s.substring(ix).trim();
- ret[1] = parseBoundSize(s, true, true);
- return ret;
- }
-
- ix = startsWithLenient(s, "gapafter", -1, true);
- if (ix > -1) {
- s = s.substring(ix).trim();
- ret[3] = parseBoundSize(s, true, true);
- return ret;
- }
-
- ix = startsWithLenient(s, new String[] {"gapx", "gapy"}, null, true);
- if (ix > -1) {
- boolean x = s.charAt(3) == 'x';
- String[] gaps = toTrimmedTokens(s.substring(ix).trim(), ' ');
- ret[x ? 1 : 0] = parseBoundSize(gaps[0], true, x);
- if (gaps.length > 1)
- ret[x ? 3 : 2] = parseBoundSize(gaps[1], true, !x);
- return ret;
- }
-
- ix = startsWithLenient(s, "gap ", 1, true);
- if (ix > -1) {
- String[] gaps = toTrimmedTokens(s.substring(ix).trim(), ' ');
-
- ret[1] = parseBoundSize(gaps[0], true, true); // left
- if (gaps.length > 1) {
- ret[3] = parseBoundSize(gaps[1], true, false); // right
- if (gaps.length > 2) {
- ret[0] = parseBoundSize(gaps[2], true, true); // top
- if (gaps.length > 3)
- ret[2] = parseBoundSize(gaps[3], true, false); // bottom
- }
- }
- return ret;
- }
-
- throw new IllegalArgumentException("Unknown Gap part: '" + s + "'");
- }
-
- private static int parseSpan(String s)
- {
- return s.length() > 0 ? Integer.parseInt(s) : LayoutUtil.INF;
- }
-
- private static Float parseFloat(String s, Float nullVal)
- {
- return s.length() > 0 ? new Float(Float.parseFloat(s)) : nullVal;
- }
-
- /** Parses a singele "min:pref:max" value. May look something like <code>"10px:20lp:30%"</code> or <code>"pref!"</code>.
- * @param s The string to parse. Not <code>null</code>.
- * @param isGap If this bound size is a gap (different empty string handling).
- * @param isHor If the size is for the horizontal dimension.
- * @return A bound size that may be <code>null</code> if the string was "null", "n" or <code>null</code>.
- */
- public static BoundSize parseBoundSize(String s, boolean isGap, boolean isHor)
- {
- if (s.length() == 0 || s.equals("null") || s.equals("n"))
- return null;
-
- boolean push = false;
- if (s.endsWith("push")) {
- if (isGap == false)
- throw new IllegalArgumentException("Only gaps can have 'push' in size. Use as separate keyword for components.");
- push = true;
- int l = s.length();
- s = s.substring(0, l - (s.endsWith(":push") ? 5 : 4));
- if (s.length() == 0)
- return new BoundSize(null, null, null, true, s);
- }
-
- String[] sizes = toTrimmedTokens(s, ':');
- String s0 = sizes[0];
-
- if (sizes.length == 1) {
- boolean hasEM = s0.endsWith("!");
- if (hasEM)
- s0 = s0.substring(0, s0.length() - 1);
- UnitValue uv = parseUnitValue(s0, null, isHor);
- return new BoundSize(((isGap || hasEM) ? uv : null), uv, (hasEM ? uv : null), push, s);
-
- } else if (sizes.length == 2) {
- return new BoundSize(parseUnitValue(s0, null, isHor), parseUnitValue(sizes[1], null, isHor), null, push, s);
- } else if (sizes.length == 3) {
- return new BoundSize(parseUnitValue(s0, null, isHor), parseUnitValue(sizes[1], null, isHor), parseUnitValue(sizes[2], null, isHor), push, s);
- } else {
- throw new IllegalArgumentException("Min:Preferred:Max size section must contain 0, 1 or 2 colons. '" + s + "'");
- }
- }
-
- /** Parses a single unit value that may also be an alignment as parsed by {@link #parseAlignKeywords(String, boolean)}.
- * @param s The string to parse. Not <code>null</code>. May look something like <code>"10px"</code> or <code>"5dlu"</code>.
- * @param isHor If the value is for the horizontal dimension.
- * @param emptyReplacement A replacement if <code>s</code> is empty. May be <code>null</code>.
- * @return The parsed unit value. May be <code>null</code>.
- */
- public static UnitValue parseUnitValueOrAlign(String s, boolean isHor, UnitValue emptyReplacement)
- {
- if (s.length() == 0)
- return emptyReplacement;
-
- UnitValue align = parseAlignKeywords(s, isHor);
- if (align != null)
- return align;
-
- return parseUnitValue(s, emptyReplacement, isHor);
- }
-
- /** Parses a single unit value. E.g. "10px" or "5in"
- * @param s The string to parse. Not <code>null</code>. May look something like <code>"10px"</code> or <code>"5dlu"</code>.
- * @param isHor If the value is for the horizontal dimension.
- * @return The parsed unit value. <code>null</code> is empty string,
- */
- public static UnitValue parseUnitValue(String s, boolean isHor)
- {
- return parseUnitValue(s, null, isHor);
- }
-
- /** Parses a single unit value.
- * @param s The string to parse. May be <code>null</code>. May look something like <code>"10px"</code> or <code>"5dlu"</code>.
- * @param emptyReplacement A replacement <code>s</code> is empty or <code>null</code>. May be <code>null</code>.
- * @param isHor If the value is for the horizontal dimension.
- * @return The parsed unit value. May be <code>null</code>.
- */
- private static UnitValue parseUnitValue(String s, UnitValue emptyReplacement, boolean isHor)
- {
- if (s == null || s.length() == 0)
- return emptyReplacement;
-
- String cs = s; // Save creation string.
- char c0 = s.charAt(0);
-
- // Remove start and end parentheses, if there.
- if (c0 == '(' && s.charAt(s.length() - 1) == ')')
- s = s.substring(1, s.length() - 1);
-
- if (c0 == 'n' && (s.equals("null") || s.equals("n")))
- return null;
-
- if (c0 == 'i' && s.equals("inf"))
- return UnitValue.INF;
-
- int oper = getOper(s);
- boolean inline = oper == UnitValue.ADD || oper == UnitValue.SUB || oper == UnitValue.MUL || oper == UnitValue.DIV;
-
- if (oper != UnitValue.STATIC) { // It is a multi-value
-
- String[] uvs;
- if (inline == false) { // If the format is of type "opr(xxx,yyy)" (compared to in-line "10%+15px")
- String sub = s.substring(4, s.length() - 1).trim();
- uvs = toTrimmedTokens(sub, ',');
- if (uvs.length == 1)
- return parseUnitValue(sub, null, isHor);
- } else {
- char delim;
- if (oper == UnitValue.ADD) {
- delim = '+';
- } else if (oper == UnitValue.SUB) {
- delim = '-';
- } else if (oper == UnitValue.MUL) {
- delim = '*';
- } else { // div left
- delim = '/';
- }
- uvs = toTrimmedTokens(s, delim);
- if (uvs.length > 2) { // More than one +-*/.
- String last = uvs[uvs.length - 1];
- String first = s.substring(0, s.length() - last.length() - 1);
- uvs = new String[] {first, last};
- }
- }
-
- if (uvs.length != 2)
- throw new IllegalArgumentException("Malformed UnitValue: '" + s + "'");
-
- UnitValue sub1 = parseUnitValue(uvs[0], null, isHor);
- UnitValue sub2 = parseUnitValue(uvs[1], null, isHor);
-
- if (sub1 == null || sub2 == null)
- throw new IllegalArgumentException("Malformed UnitValue. Must be two sub-values: '" + s + "'");
-
- return new UnitValue(isHor, oper, sub1, sub2, cs);
- } else {
- try {
- String[] numParts = getNumTextParts(s);
- float value = numParts[0].length() > 0 ? Float.parseFloat(numParts[0]) : 1; // e.g. "related" has no number part..
-
- return new UnitValue(value, numParts[1], isHor, oper, cs);
-
- } catch(Exception e) {
- throw new IllegalArgumentException("Malformed UnitValue: '" + s + "'");
- }
- }
- }
-
- /** Parses alignment keywords and returns the approprieate <code>UnitValue</code>.
- * @param s The string to parse. Not <code>null</code>.
- * @param isHor If alignments for horizontal is checked. <code>false</code> means vertical.
- * @return The unit value or <code>null</code> if not recognized (no exception).
- */
- static UnitValue parseAlignKeywords(String s, boolean isHor)
- {
- if (startsWithLenient(s, "center", 1, false) != -1)
- return UnitValue.CENTER;
-
- if (isHor) {
- if (startsWithLenient(s, "left", 1, false) != -1)
- return UnitValue.LEFT;
-
- if (startsWithLenient(s, "right", 1, false) != -1)
- return UnitValue.RIGHT;
-
- if (startsWithLenient(s, "leading", 4, false) != -1)
- return UnitValue.LEADING;
-
- if (startsWithLenient(s, "trailing", 5, false) != -1)
- return UnitValue.TRAILING;
-
- if (startsWithLenient(s, "label", 5, false) != -1)
- return UnitValue.LABEL;
-
- } else {
-
- if (startsWithLenient(s, "baseline", 4, false) != -1)
- return UnitValue.BASELINE_IDENTITY;
-
- if (startsWithLenient(s, "top", 1, false) != -1)
- return UnitValue.TOP;
-
- if (startsWithLenient(s, "bottom", 1, false) != -1)
- return UnitValue.BOTTOM;
- }
-
- return null;
- }
-
- /** Splits a text-number combination such as "hello 10.0" into <code>{"hello", "10.0"}</code>.
- * @param s The string to split. Not <code>null</code>. Needs be be resonably formatted since the method
- * only finds the first 0-9 or . and cuts the string in half there.
- * @return Always length 2 and no <code>null</code> elements. Elements are "" if no part found.
- */
- private static String[] getNumTextParts(String s)
- {
- for (int i = 0, iSz = s.length(); i < iSz; i++) {
- char c = s.charAt(i);
- if (c == ' ')
- throw new IllegalArgumentException("Space in UnitValue: '" + s + "'");
-
- if ((c < '0' || c > '9') && c != '.' && c != '-')
- return new String[] {s.substring(0, i).trim(), s.substring(i).trim()};
- }
- return new String[] {s, ""};
- }
-
- /** Returns the operation depending on the start character.
- * @param s The string to check. Not <code>null</code>.
- * @return E.g. UnitValue.ADD, UnitValue.SUB or UnitValue.STATIC. Returns negative value for in-line operations.
- */
- private static int getOper(String s)
- {
- int len = s.length();
- if (len < 3)
- return UnitValue.STATIC;
-
- if (len > 5 && s.charAt(3) == '(' && s.charAt(len - 1) == ')') {
- if (s.startsWith("min("))
- return UnitValue.MIN;
-
- if (s.startsWith("max("))
- return UnitValue.MAX;
-
- if (s.startsWith("mid("))
- return UnitValue.MID;
- }
-
- // Try in-line add/sub. E.g. "pref+10px".
- for (int j = 0; j < 2; j++) { // First +- then */ (precedence)
- for (int i = len - 1, p = 0; i > 0; i--) {
- char c = s.charAt(i);
- if (c == ')') {
- p++;
- } else if (c == '(') {
- p--;
- } else if (p == 0) {
- if (j == 0) {
- if (c == '+')
- return UnitValue.ADD;
- if (c == '-')
- return UnitValue.SUB;
- } else {
- if (c == '*')
- return UnitValue.MUL;
- if (c == '/')
- return UnitValue.DIV;
- }
- }
- }
- }
- return UnitValue.STATIC;
- }
-
- /** Returns if a string shares at least a specified numbers starting characters with a number of matches.
- * <p>
- * This method just excercises {@link #startsWithLenient(String, String, int, boolean)} with every one of
- * <code>matches</code> and <code>minChars</code>.
- * @param s The string to check. Not <code>null</code>.
- * @param matches A number of possible starts for <code>s</code>.
- * @param minChars The mimimum number of characters to match for every element in <code>matches</code>. Needs
- * to be of same length as <code>matches</code>. Can be <code>null</code>.
- * @param acceptTrailing If after the required number of charecters are matched onrecognized characters that are not
- * in one of the the <code>matches</code> string should be accepted. For instance if "abczz" should be matched with
- * "abcdef" and min chars 3.
- * @return The index of the first unmatched character if <code>minChars</code> was reached or <code>-1</code> if a match was not
- * found.
- */
- private static int startsWithLenient(String s, String[] matches, int[] minChars, boolean acceptTrailing)
- {
- for (int i = 0; i < matches.length; i++) {
- int minChar = minChars != null ? minChars[i] : -1;
- int ix = startsWithLenient(s, matches[i], minChar, acceptTrailing);
- if (ix > -1)
- return ix;
- }
- return -1;
- }
-
- /** Returns if a string shares at least a specified numbers starting characters with a match.
- * @param s The string to check. Not <code>null</code> and must be trimmed.
- * @param match The possible start for <code>s</code>. Not <code>null</code> and must be trimmed.
- * @param minChars The mimimum number of characters to match to <code>s</code> for it this to be considered a match. -1 means
- * the full length of <code>match</code>.
- * @param acceptTrailing If after the required number of charecters are matched unrecognized characters that are not
- * in one of the the <code>matches</code> string should be accepted. For instance if "abczz" should be matched with
- * "abcdef" and min chars 3.
- * @return The index of the first unmatched character if <code>minChars</code> was reached or <code>-1</code> if a match was not
- * found.
- */
- private static int startsWithLenient(String s, String match, int minChars, boolean acceptTrailing)
- {
- if (s.charAt(0) != match.charAt(0)) // Fast sanity check.
- return -1;
-
- if (minChars == -1)
- minChars = match.length();
-
- int sSz = s.length();
- if (sSz < minChars)
- return -1;
-
- int mSz = match.length();
- int sIx = 0;
- for (int mIx = 0; mIx < mSz; sIx++, mIx++) {
- while (sIx < sSz && (s.charAt(sIx) == ' ' || s.charAt(sIx) == '_')) // Disregard spaces and _
- sIx++;
-
- if (sIx >= sSz || s.charAt(sIx) != match.charAt(mIx))
- return mIx >= minChars && (acceptTrailing || sIx >= sSz) && (sIx >= sSz || s.charAt(sIx - 1) == ' ') ? sIx : -1;
- }
-// return (sIx >= sSz || acceptTrailing) && (sIx >= sSz || s.charAt(sIx) == ' ') ? sIx : -1;
- return sIx >= sSz || acceptTrailing ||s.charAt(sIx) == ' ' ? sIx : -1;
- }
-
- /** Parses a string and returns it in those parts of the string that are separated with a <code>sep</code> character.
- * <p>
- * separator characters within parentheses will not be counted or handled in any way, whatever the depth.
- * @param s The string to parse. If it starts and/or ends with a <code>sep</code> the first and/or last element returned will be "". If
- * two <code>sep</code> are next to eachother and empty element will be "between" the periods. The <code>sep</code> themselves will never be returned.
- * @param sep The separator char.
- * @return Those parts of the string that are separated with <code>sep</code>. Never null and at least of size 1
- */
- private final static String[] toTrimmedTokens(String s, char sep)
- {
- int toks = 0, sSize = s.length();
-
- // Count the sep:s
- int p = 0;
- for(int i = 0; i < sSize; i++) {
- char c = s.charAt(i);
- if (c == '(') {
- p++;
- } else if (c == ')') {
- p--;
- } else if (p == 0 && c == sep) {
- toks++;
- }
- if (p < 0)
- throw new IllegalArgumentException("Unbalanced parentheses: '" + s + "'");
- }
- if (p != 0)
- throw new IllegalArgumentException("Unbalanced parentheses: '" + s + "'");
-
- if (toks == 0)
- return new String [] {s.trim()};
-
- String[] retArr = new String[toks + 1];
-
- int st = 0, pNr = 0;
- p = 0;
- for (int i = 0; i < sSize; i++) {
-
- char c = s.charAt(i);
- if (c == '(') {
- p++;
- } else if (c == ')') {
- p--;
- } else if (p == 0 && c == sep) {
- retArr[pNr++] = s.substring(st, i).trim();
- st = i + 1;
- }
- }
-
- retArr[pNr++] = s.substring(st, sSize).trim();
- return retArr;
- }
-
- /** Parses "AAA[BBB]CCC[DDD]EEE" into {"AAA", "BBB", "CCC", "DDD", "EEE", "FFF"}. Handles empty parts. Will always start and end outside
- * a [] block so that the number of returned elemets will always be uneven and at least of length 3.
- * <p>
- * "|" is interprated as "][".
- * @param s The string. Might be "" but not null. Should be trimmed.
- * @return The string divided into elements. Never <code>null</code> and at least of length 3.
- * @throws IllegalArgumentException If a [] mismatch of some kind. (If not same [ as ] count or if the interleave.)
- */
- private final static ArrayList<String> getRowColAndGapsTrimmed(String s)
- {
- if (s.indexOf('|') != -1)
- s = s.replaceAll("\\|", "][");
-
- ArrayList<String> retList = new ArrayList<String>(Math.max(s.length() >> 2 + 1, 3)); // Aprox return length.
- int s0 = 0, s1 = 0; // '[' and ']' count.
- int st = 0; // Start of "next token to add".
- for (int i = 0, iSz = s.length(); i < iSz; i++) {
- char c = s.charAt(i);
- if (c == '[') {
- s0++;
- } else if (c == ']') {
- s1++;
- } else {
- continue;
- }
-
- if (s0 != s1 && (s0 - 1) != s1)
- break; // Wrong [ or ] found. Break for throw.
-
- retList.add(s.substring(st, i).trim());
- st = i + 1;
- }
- if (s0 != s1)
- throw new IllegalArgumentException("'[' and ']' mismatch in row/column format string: " + s);
-
- if (s0 == 0) {
- retList.add("");
- retList.add(s);
- retList.add("");
- } else if (retList.size() % 2 == 0) {
- retList.add(s.substring(st, s.length()));
- }
-
- return retList;
- }
-
- /** Makes <code>null</code> "", trimms and converts to lower case.
- * @param s The string
- * @return Not null.
- */
- public static final String prepare(String s)
- {
- return s != null ? s.trim().toLowerCase() : "";
- }
-
-// /** Tests to serialize and deserialize the object with both XMLEncoder/Decoder and through Serializable
-// * @param o The object to serialize
-// * @return The same object after a tri through the process.
-// */
-// public static final Object serializeTest(Object o)
-// {
-// try {
-// ByteArrayOutputStream barr = new ByteArrayOutputStream();
-// XMLEncoder enc = new XMLEncoder(barr);
-// enc.writeObject(o);
-// enc.close();
-//
-// XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(barr.toByteArray()));
-// o = dec.readObject();
-// dec.close();
-// } catch (Exception e) {
-// e.printStackTrace();
-// }
-//
-// try {
-// ByteArrayOutputStream barr = new ByteArrayOutputStream();
-// ObjectOutputStream oos = new ObjectOutputStream(barr);
-// oos.writeObject(o);
-// oos.close();
-//
-// ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
-// o = ois.readObject();
-// ois.close();
-// } catch (Exception e) {
-// e.printStackTrace();
-// }
-//
-// return o;
-// }
-}
+package net.miginfocom.layout; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** Parses string constraints. + */ +public final class ConstraintParser +{ + private ConstraintParser() + { + } + + /** Parses the layout constraints and stores the parsed values in the transient (cache) member varables. + * @param s The String to parse. Should not be <code>null</code> and <b>must be lower case and trimmed</b>. + * @throws RuntimeException if the constaint was not valid. + * @return The parsed constraint. Never <code>null</code>. + */ + public static LC parseLayoutConstraint(String s) + { + LC lc = new LC(); + if (s.length() == 0) + return lc; + + String[] parts = toTrimmedTokens(s, ','); + + // First check for "ltr" or "rtl" since that will affect the interpretation of the other constraints. + for (int i = 0; i < parts.length; i++) { + String part = parts[i]; + if (part == null) + continue; + + int len = part.length(); + if (len == 3 || len == 11) { // Optimization + if (part.equals("ltr") || part.equals("rtl") || part.equals("lefttoright") || part.equals("righttoleft")) { + lc.setLeftToRight(part.charAt(0) == 'l' ? Boolean.TRUE : Boolean.FALSE); + parts[i] = null; // So we will not try to interpret it again + } + + if (part.equals("ttb") || part.equals("btt") || part.equals("toptobottom") || part.equals("bottomtotop")) { + lc.setTopToBottom(part.charAt(0) == 't'); + parts[i] = null; // So we will not try to interpret it again + } + } + } + + for (int i = 0; i < parts.length; i++) { + String part = parts[i]; + if (part == null || part.length() == 0) + continue; + + try { + int ix = -1; + char c = part.charAt(0); + + if (c == 'w') { + ix = startsWithLenient(part, "wrap", -1, true); + if (ix > -1) { + String num = part.substring(ix).trim(); + lc.setWrapAfter(num.length() != 0 ? Integer.parseInt(num) : 0); + continue; + } + } + + if (c == 'g') { + if (part.startsWith("gapx ")) { + lc.setGridGapX(parseBoundSize(part.substring(5).trim(), true, true)); + continue; + } + + if (part.startsWith("gapy ")) { + lc.setGridGapY(parseBoundSize(part.substring(5).trim(), true, false)); + continue; + } + + if (part.startsWith("gap ")) { + String[] gaps = toTrimmedTokens(part.substring(4).trim(), ' '); + lc.setGridGapX(parseBoundSize(gaps[0], true, true)); + lc.setGridGapY(gaps.length > 1 ? parseBoundSize(gaps[1], true, false) : lc.getGridGapX()); + continue; + } + } + + if (c == 'd') { + ix = startsWithLenient(part, "debug", 5, true); + if (ix > -1) { + String millis = part.substring(ix).trim(); + lc.setDebugMillis(millis.length() > 0 ? Integer.parseInt(millis) : 1000); + continue; + } + } + + if (c == 'n') { + if (part.equals("nogrid")) { + lc.setNoGrid(true); + continue; + } + + if (part.equals("nocache")) { + lc.setNoCache(true); + continue; + } + + if (part.equals("novisualpadding")) { + lc.setVisualPadding(false); + continue; + } + } + + if (c == 'f') { + if (part.equals("fill") || part.equals("fillx") || part.equals("filly")) { + lc.setFillX(part.length() == 4 || part.charAt(4) == 'x'); + lc.setFillY(part.length() == 4 || part.charAt(4) == 'y'); + continue; + } + + if (part.equals("flowy")) { + lc.setFlowX(false); + continue; + } + + if (part.equals("flowx")) { + lc.setFlowX(true); // This is the default but added for consistency + continue; + } + } + + if (c == 'i') { + ix = startsWithLenient(part, "insets", 3, true); + if (ix > -1) { + String insStr = part.substring(ix).trim(); + UnitValue[] ins = parseInsets(insStr, true); + LayoutUtil.putCCString(ins, insStr); + lc.setInsets(ins); + continue; + } + } + + if (c == 'a') { + ix = startsWithLenient(part, new String[] {"aligny", "ay"}, new int[] {6, 2}, true); + if (ix > -1) { + lc.setAlignY(parseUnitValueOrAlign(part.substring(ix).trim(), false, null)); + continue; + } + + ix = startsWithLenient(part, new String[] {"alignx", "ax"}, new int[] {6, 2}, true); + if (ix > -1) { + lc.setAlignX(parseUnitValueOrAlign(part.substring(ix).trim(), true, null)); + continue; + } + + ix = startsWithLenient(part, "align", 2, true); + if (ix > -1) { + String[] gaps = toTrimmedTokens(part.substring(ix).trim(), ' '); + lc.setAlignX(parseUnitValueOrAlign(gaps[0], true, null)); + lc.setAlignY(gaps.length > 1 ? parseUnitValueOrAlign(gaps[1], false, null) : lc.getAlignX()); + continue; + } + } + + if (c == 'h' && part.startsWith("hidemode ")) { + lc.setHideMode(Integer.parseInt(part.substring(9))); + continue; + } + + if (lc.getAlignX() == null) { + UnitValue alignX = parseAlignKeywords(part, true); + if (alignX != null) { + lc.setAlignX(alignX); + continue; + } + } + + UnitValue alignY = parseAlignKeywords(part, false); + if (alignY != null) { + lc.setAlignY(alignY); + continue; + } + + throw new IllegalArgumentException("Unknown Constraint: '" + part + "'\n"); + + } catch (Exception ex) { + throw new IllegalArgumentException("Illegal Constraint: '" + part + "'\n" + ex.getMessage()); + } + } + +// lc = (LC) serializeTest(lc); + + return lc; + } + + /** Parses the column or rows constraints. They normally looks something like <code>"[min:pref]rel[10px][]"</code>. + * @param s The string to parse. Not <code>null</code>. + * @return An array of {@link DimConstraint}s that is as manu are there exist "[...]" sections in the string that is parsed. + * @throws RuntimeException if the constaint was not valid. + */ + public static AC parseRowConstraints(String s) + { + return parseAxisConstraint(s, false); + } + + /** Parses the column or rows constraints. They normally looks something like <code>"[min:pref]rel[10px][]"</code>. + * @param s The string to parse. Not <code>null</code>. + * @return An array of {@link DimConstraint}s that is as manu are there exist "[...]" sections in the string that is parsed. + * @throws RuntimeException if the constaint was not valid. + */ + public static AC parseColumnConstraints(String s) + { + return parseAxisConstraint(s, true); + } + + /** Parses the column or rows constraints. They normally looks something like <code>"[min:pref]rel[10px][]"</code>. + * @param s The string to parse. Not <code>null</code>. + * @param isCols If this for columns rather than rows. + * @return An array of {@link DimConstraint}s that is as manu are there exist "[...]" sections in the string that is parsed. + * @throws RuntimeException if the constaint was not valid. + */ + private static AC parseAxisConstraint(String s, boolean isCols) + { + s = s.trim(); + + if (s.length() == 0) + return new AC(); // Short circuit for performance. + + s = s.toLowerCase(); + + ArrayList<String> parts = getRowColAndGapsTrimmed(s); + + BoundSize[] gaps = new BoundSize[(parts.size() >> 1) + 1]; + for (int i = 0, iSz = parts.size(), gIx = 0; i < iSz; i += 2, gIx++) + gaps[gIx] = parseBoundSize(parts.get(i), true, isCols); + + DimConstraint[] colSpecs = new DimConstraint[parts.size() >> 1]; + for (int i = 0, gIx = 0; i < colSpecs.length; i++, gIx++) { + if (gIx >= gaps.length - 1) + gIx = gaps.length - 2; + + colSpecs[i] = parseDimConstraint(parts.get((i << 1) + 1), gaps[gIx], gaps[gIx + 1], isCols); + } + + AC ac = new AC(); + ac.setConstaints(colSpecs); + +// ac = (AC) serializeTest(ac); + + return ac; + } + + /** Parses a single column or row constriant. + * @param s The single constrint to parse. May look something like <code>"min:pref,fill,grow"</code>. Should not be <code>null</code> and <b>must + * be lower case and trimmed</b>. + * @param gapBefore The default gap "before" the column/row constraint. Can be overridden with a <code>"gap"</code> section within <code>s</code>. + * @param gapAfter The default gap "after" the column/row constraint. Can be overridden with a <code>"gap"</code> section within <code>s</code>. + * @param isCols If the constraints are column constraints rather than row constraints. + * @return A single constraint. Never <code>null</code>. + * @throws RuntimeException if the constaint was not valid. + */ + private static DimConstraint parseDimConstraint(String s, BoundSize gapBefore, BoundSize gapAfter, boolean isCols) + { + DimConstraint dimConstraint = new DimConstraint(); + + // Default values. + dimConstraint.setGapBefore(gapBefore); + dimConstraint.setGapAfter(gapAfter); + + String[] parts = toTrimmedTokens(s, ','); + for (int i = 0; i < parts.length; i++) { + String part = parts[i]; + try { + if (part.length() == 0) + continue; + + if (part.equals("fill")) { + dimConstraint.setFill(true); + dimConstraint.setAlign(null); // Can not have both fill and alignment + continue; + } + + if (part.equals("nogrid")) { + dimConstraint.setNoGrid(true); + continue; + } + + int ix = -1; + char c = part.charAt(0); + + if (c == 's') { + ix = startsWithLenient(part, new String[] {"sizegroup", "sg"}, new int[] {5, 2}, true); + if (ix > -1) { + dimConstraint.setSizeGroup(part.substring(ix).trim()); + continue; + } + + + ix = startsWithLenient(part, new String[] {"shrinkprio", "shp"}, new int[] {10, 3}, true); + if (ix > -1) { + dimConstraint.setShrinkPriority(Integer.parseInt(part.substring(ix).trim())); + continue; + } + + ix = startsWithLenient(part, "shrink", 6, true); + if (ix > -1) { + dimConstraint.setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + } + + if (c == 'g') { + ix = startsWithLenient(part, new String[] {"growpriority", "gp"}, new int[] {5, 2}, true); + if (ix > -1) { + dimConstraint.setGrowPriority(Integer.parseInt(part.substring(ix).trim())); + continue; + } + + ix = startsWithLenient(part, "grow", 4, true); + if (ix > -1) { + dimConstraint.setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + } + + if (c == 'a') { + ix = startsWithLenient(part, "align", 2, true); + if (ix > -1) { + if (dimConstraint.isFill() == false) // Swallow, but ignore if fill is set. + dimConstraint.setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), isCols, null)); + continue; + } + } + + UnitValue align = parseAlignKeywords(part, isCols); + if (align != null) { + if (dimConstraint.isFill() == false) // Swallow, but ignore if fill is set. + dimConstraint.setAlign(align); + continue; + } + + // Only min:pref:max still left that is ok + dimConstraint.setSize(parseBoundSize(part, false, isCols)); + + } catch (Exception ex) { + throw new IllegalArgumentException("Illegal contraint: '" + part + "'\n" + ex.getMessage()); + } + } + return dimConstraint; + } + + /** Parses all component constraints and stores the parsed values in the transient (cache) member varables. + * @param constrMap The constraints as <code>String</code>s. Strings <b>must be lower case and trimmed</b> + * @return The parsed constraints. Never <code>null</code>. + */ + public static Map<ComponentWrapper, CC> parseComponentConstraints(Map<ComponentWrapper, String> constrMap) + { + HashMap<ComponentWrapper, CC> flowConstrMap = new HashMap<ComponentWrapper, CC>(); + + for (Iterator<Map.Entry<ComponentWrapper, String>> it = constrMap.entrySet().iterator(); it.hasNext();) { + Map.Entry<ComponentWrapper, String> entry = it.next(); + flowConstrMap.put(entry.getKey(), parseComponentConstraint(entry.getValue())); + } + + return flowConstrMap; + } + + /** Parses one component constraint and returns the parsed value. + * @param s The string to parse. Should not be <code>null</code> and <b>must be lower case and trimmed</b>. + * @throws RuntimeException if the constaint was not valid. + * @return The parsed constraint. Never <code>null</code>. + */ + public static CC parseComponentConstraint(String s) + { + CC cc = new CC(); + + if (s.length() == 0) + return cc; + + String[] parts = toTrimmedTokens(s, ','); + + for (int i = 0; i < parts.length; i++) { + String part = parts[i]; + try { + if (part.length() == 0) + continue; + + int ix = -1; + char c = part.charAt(0); + + if (c == 'n') { + if (part.equals("north")) { + cc.setDockSide(0); + continue; + } + + if (part.equals("newline")) { + cc.setNewline(true); + continue; + } + + if (part.startsWith("newline ")) { + String gapSz = part.substring(7).trim(); + cc.setNewlineGapSize(parseBoundSize(gapSz, true, true)); + continue; + } + } + + if (c == 'f' && (part.equals("flowy") || part.equals("flowx"))) { + cc.setFlowX(part.charAt(4) == 'x' ? Boolean.TRUE : Boolean.FALSE); + continue; + } + + if (c == 's') { + ix = startsWithLenient(part, "skip", 4, true); + if (ix > -1) { + String num = part.substring(ix).trim(); + cc.setSkip(num.length() != 0 ? Integer.parseInt(num) : 1); + continue; + } + + ix = startsWithLenient(part, "split", 5, true); + if (ix > -1) { + String split = part.substring(ix).trim(); + cc.setSplit(split.length() > 0 ? Integer.parseInt(split) : LayoutUtil.INF); + continue; + } + + if (part.equals("south")) { + cc.setDockSide(2); + continue; + } + + ix = startsWithLenient(part, new String[] {"spany","sy"}, new int[] {5, 2}, true); + if (ix > -1) { + cc.setSpanY(parseSpan(part.substring(ix).trim())); + continue; + } + + ix = startsWithLenient(part, new String[] {"spanx","sx"}, new int[] {5, 2}, true); + if (ix > -1) { + cc.setSpanX(parseSpan(part.substring(ix).trim())); + continue; + } + + ix = startsWithLenient(part, "span", 4, true); + if (ix > -1) { + String[] spans = toTrimmedTokens(part.substring(ix).trim(), ' '); + cc.setSpanX(spans[0].length() > 0 ? Integer.parseInt(spans[0]) : LayoutUtil.INF); + cc.setSpanY(spans.length > 1 ? Integer.parseInt(spans[1]) : 1); + continue; + } + + ix = startsWithLenient(part, "shrinkx", 7, true); + if (ix > -1) { + cc.getHorizontal().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + + ix = startsWithLenient(part, "shrinky", 7, true); + if (ix > -1) { + cc.getVertical().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + + ix = startsWithLenient(part, "shrink", 6, false); + if (ix > -1) { + String[] shrinks = toTrimmedTokens(part.substring(ix).trim(), ' '); + cc.getHorizontal().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + if (shrinks.length > 1) + cc.getVertical().setShrink(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + + ix = startsWithLenient(part, new String[] {"shrinkprio", "shp"}, new int[] {10, 3}, true); + if (ix > -1) { + String sp = part.substring(ix).trim(); + if (sp.startsWith("x") || sp.startsWith("y")) { // To gandle "gpx", "gpy", "shrinkpriorityx", shrinkpriorityy" + (sp.startsWith("x") ? cc.getHorizontal() : cc.getVertical()).setShrinkPriority(Integer.parseInt(sp.substring(2))); + } else { + String[] shrinks = toTrimmedTokens(sp, ' '); + cc.getHorizontal().setShrinkPriority(Integer.parseInt(shrinks[0])); + if (shrinks.length > 1) + cc.getVertical().setShrinkPriority(Integer.parseInt(shrinks[1])); + } + continue; + } + + ix = startsWithLenient(part, new String[] {"sizegroupx", "sizegroupy", "sgx", "sgy"}, new int[] {9, 9, 2, 2}, true); + if (ix > -1) { + String sg = part.substring(ix).trim(); + char lc = part.charAt(ix - 1); + if (lc != 'y') + cc.getHorizontal().setSizeGroup(sg); + if (lc != 'x') + cc.getVertical().setSizeGroup(sg); + continue; + } + } + + if (c == 'g') { + ix = startsWithLenient(part, "growx", 5, true); + if (ix > -1) { + cc.getHorizontal().setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + + ix = startsWithLenient(part, "growy", 5, true); + if (ix > -1) { + cc.getVertical().setGrow(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + + ix = startsWithLenient(part, "grow", 4, false); + if (ix > -1) { + String[] grows = toTrimmedTokens(part.substring(ix).trim(), ' '); + cc.getHorizontal().setGrow(parseFloat(grows[0], ResizeConstraint.WEIGHT_100)); + cc.getVertical().setGrow(parseFloat(grows.length > 1 ? grows[1] : "", ResizeConstraint.WEIGHT_100)); + continue; + } + + ix = startsWithLenient(part, new String[] {"growprio", "gp"}, new int[] {8, 2}, true); + if (ix > -1) { + String gp = part.substring(ix).trim(); + char c0 = gp.length() > 0 ? gp.charAt(0) : ' '; + if (c0 == 'x' || c0 == 'y') { // To gandle "gpx", "gpy", "growpriorityx", growpriorityy" + (c0 == 'x' ? cc.getHorizontal() : cc.getVertical()).setGrowPriority(Integer.parseInt(gp.substring(2))); + } else { + String[] grows = toTrimmedTokens(gp, ' '); + cc.getHorizontal().setGrowPriority(Integer.parseInt(grows[0])); + if (grows.length > 1) + cc.getVertical().setGrowPriority(Integer.parseInt(grows[1])); + } + continue; + } + + if (part.startsWith("gap")) { + BoundSize[] gaps = parseGaps(part); + if (gaps[0] != null) + cc.getVertical().setGapBefore(gaps[0]); + if (gaps[1] != null) + cc.getHorizontal().setGapBefore(gaps[1]); + if (gaps[2] != null) + cc.getVertical().setGapAfter(gaps[2]); + if (gaps[3] != null) + cc.getHorizontal().setGapAfter(gaps[3]); + continue; + } + } + + if (c == 'a') { + ix = startsWithLenient(part, new String[] {"aligny", "ay"}, new int[] {6, 2}, true); + if (ix > -1) { + cc.getVertical().setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), false, null)); + continue; + } + + ix = startsWithLenient(part, new String[] {"alignx", "ax"}, new int[] {6, 2}, true); + if (ix > -1) { + cc.getHorizontal().setAlign(parseUnitValueOrAlign(part.substring(ix).trim(), true, null)); + continue; + } + + ix = startsWithLenient(part, "align", 2, true); + if (ix > -1) { + String[] gaps = toTrimmedTokens(part.substring(ix).trim(), ' '); + cc.getHorizontal().setAlign(parseUnitValueOrAlign(gaps[0], true, null)); + if (gaps.length > 1) + cc.getVertical().setAlign(parseUnitValueOrAlign(gaps[1], false, null)); + continue; + } + } + + if ((c == 'x' || c == 'y') && part.length() > 2) { + char c2 = part.charAt(1); + if (c2 == ' ' || (c2 == '2' && part.charAt(2) == ' ')) { + if (cc.getPos() == null) { + cc.setPos(new UnitValue[4]); + } else if (cc.isBoundsInGrid() == false) { + throw new IllegalArgumentException("Can not combine 'position' with 'x/y/x2/y2' keywords."); + } + + int edge = (c == 'x' ? 0 : 1) + (c2 == '2' ? 2 : 0); + UnitValue[] pos = cc.getPos(); + pos[edge] = parseUnitValue(part.substring(2).trim(), null, c == 'x'); + cc.setPos(pos); + cc.setBoundsInGrid(true); + continue; + } + } + + if (c == 'c') { + ix = startsWithLenient(part, "cell", 4, true); + if (ix > -1) { + String[] grs = toTrimmedTokens(part.substring(ix).trim(), ' '); + if (grs.length < 2) + throw new IllegalArgumentException("At least two integers must follow " + part); + cc.setCellX(Integer.parseInt(grs[0])); + cc.setCellY(Integer.parseInt(grs[1])); + if (grs.length > 2) + cc.setSpanX(Integer.parseInt(grs[2])); + if (grs.length > 3) + cc.setSpanY(Integer.parseInt(grs[3])); + continue; + } + } + + if (c == 'p') { + ix = startsWithLenient(part, "pos", 3, true); + if (ix > -1) { + if (cc.getPos() != null && cc.isBoundsInGrid()) + throw new IllegalArgumentException("Can not combine 'pos' with 'x/y/x2/y2' keywords."); + + String[] pos = toTrimmedTokens(part.substring(ix).trim(), ' '); + UnitValue[] bounds = new UnitValue[4]; + for (int j = 0; j < pos.length; j++) + bounds[j] = parseUnitValue(pos[j], null, j % 2 == 0); + + if (bounds[0] == null && bounds[2] == null || bounds[1] == null && bounds[3] == null) + throw new IllegalArgumentException("Both x and x2 or y and y2 can not be null!"); + + cc.setPos(bounds); + cc.setBoundsInGrid(false); + continue; + } + + ix = startsWithLenient(part, "pad", 3, true); + if (ix > -1) { + UnitValue[] p = parseInsets(part.substring(ix).trim(), false); + cc.setPadding(new UnitValue[] { + p[0], + p.length > 1 ? p[1] : null, + p.length > 2 ? p[2] : null, + p.length > 3 ? p[3] : null}); + continue; + } + + ix = startsWithLenient(part, "pushx", 5, true); + if (ix > -1) { + cc.setPushX(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + + ix = startsWithLenient(part, "pushy", 5, true); + if (ix > -1) { + cc.setPushY(parseFloat(part.substring(ix).trim(), ResizeConstraint.WEIGHT_100)); + continue; + } + + ix = startsWithLenient(part, "push", 4, false); + if (ix > -1) { + String[] pushs = toTrimmedTokens(part.substring(ix).trim(), ' '); + cc.setPushX(parseFloat(pushs[0], ResizeConstraint.WEIGHT_100)); + cc.setPushY(parseFloat(pushs.length > 1 ? pushs[1] : "", ResizeConstraint.WEIGHT_100)); + continue; + } + } + + if (c == 't') { + ix = startsWithLenient(part, "tag", 3, true); + if (ix > -1) { + cc.setTag(part.substring(ix).trim()); + continue; + } + } + + if (c == 'w' || c == 'h') { + if (part.equals("wrap")) { + cc.setWrap(true); + continue; + } + + if (part.startsWith("wrap ")) { + String gapSz = part.substring(5).trim(); + cc.setWrapGapSize(parseBoundSize(gapSz, true, true)); + continue; + } + + boolean isHor = c == 'w'; + if (isHor && (part.startsWith("w ") || part.startsWith("width "))) { + String uvStr = part.substring(part.charAt(1) == ' ' ? 2 : 6).trim(); + BoundSize wbs = parseBoundSize(uvStr, false, true); + LayoutUtil.putCCString(wbs, uvStr); + cc.getHorizontal().setSize(wbs); + continue; + } + + if (!isHor && (part.startsWith("h ") || part.startsWith("height "))) { + String uvStr = part.substring(part.charAt(1) == ' ' ? 2 : 7).trim(); + BoundSize hbs = parseBoundSize(uvStr, false, false); + LayoutUtil.putCCString(hbs, uvStr); + cc.getVertical().setSize(hbs); + continue; + } + + if (part.startsWith("wmin ") || part.startsWith("wmax ") || part.startsWith("hmin ") || part.startsWith("hmax ")) { + String uvStr = part.substring(5).trim(); + if (uvStr.length() > 0) { + UnitValue uv = parseUnitValue(uvStr, null, isHor); + boolean isMin = part.charAt(3) == 'n'; + DimConstraint dc = isHor ? cc.getHorizontal() : cc.getVertical(); + dc.setSize(new BoundSize( + isMin ? uv : (dc.getSize() != null ? dc.getSize().getMin() : null), + dc.getSize() != null ? dc.getSize().getPreferred() : null, + isMin ? (dc.getSize() != null ? dc.getSize().getMax() : null) : uv, + uvStr + )); + continue; + } + } + + if (part.equals("west")) { + cc.setDockSide(1); +// cc.getVertical().setGrow(ResizeConstraint.WEIGHT_100); + continue; + } + + if (part.startsWith("hidemode ")) { + cc.setHideMode(Integer.parseInt(part.substring(9))); + continue; + } + } + + if (c == 'i' && part.startsWith("id ")) { + cc.setId(part.substring(3).trim()); + int dIx = cc.getId().indexOf('.'); + if (dIx == 0 || dIx == cc.getId().length() - 1) + throw new IllegalArgumentException("Dot must not be first or last!"); + + continue; + } + + if (c == 'e') { + if (part.equals("east")) { + cc.setDockSide(3); +// cc.getVertical().setGrow(ResizeConstraint.WEIGHT_100); + continue; + } + + if (part.equals("external")) { + cc.setExternal(true); + continue; + } + + ix = startsWithLenient(part, new String[] {"endgroupx", "endgroupy", "egx", "egy"}, new int[] {-1, -1, -1, -1}, true); + if (ix > -1) { + String sg = part.substring(ix).trim(); + char lc = part.charAt(ix - 1); + DimConstraint dc = (lc == 'x' ? cc.getHorizontal() : cc.getVertical()); + dc.setEndGroup(sg); + continue; + } + } + + if (c == 'd') { + if (part.equals("dock north")) { + cc.setDockSide(0); + continue; + } + if (part.equals("dock west")) { + cc.setDockSide(1); + continue; + } + if (part.equals("dock south")) { + cc.setDockSide(2); + continue; + } + if (part.equals("dock east")) { + cc.setDockSide(3); + continue; + } + + if (part.equals("dock center")) { + cc.getHorizontal().setGrow(new Float(100f)); + cc.getVertical().setGrow(new Float(100f)); + continue; + } + } + + UnitValue horAlign = parseAlignKeywords(part, true); + if (horAlign != null) { + cc.getHorizontal().setAlign(horAlign); + continue; + } + + UnitValue verAlign = parseAlignKeywords(part, false); + if (verAlign != null) { + cc.getVertical().setAlign(verAlign); + continue; + } + + throw new IllegalArgumentException("Unknown keyword."); + + } catch (Exception ex) { + throw new IllegalArgumentException("Illegal Constraint: '" + part + "'\n" + ex.getMessage()); + } + } + +// cc = (CC) serializeTest(cc); + + return cc; + } + + /** Parses insets which consists of 1-4 <code>UnitValue</code>s. + * @param s The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing. + * @param acceptPanel If "panel" and "dialog" should be accepted. They are used to access platform defaults. + * @return An array of length 4 with the parsed insets. + * @throws IllegalArgumentException if the parsing could not be done. + */ + public static UnitValue[] parseInsets(String s, boolean acceptPanel) + { + if (s.length() == 0 || s.equals("dialog") || s.equals("panel")) { + if (acceptPanel == false) + throw new IllegalAccessError("Insets now allowed: " + s + "\n"); + + boolean isPanel = s.startsWith("p"); + UnitValue[] ins = new UnitValue[4]; + for (int j = 0; j < 4; j++) + ins[j] = isPanel ? PlatformDefaults.getPanelInsets(j) : PlatformDefaults.getDialogInsets(j); + + return ins; + } else { + String[] insS = toTrimmedTokens(s, ' '); + UnitValue[] ins = new UnitValue[4]; + for (int j = 0; j < 4; j++) { + UnitValue insSz = parseUnitValue(insS[j < insS.length ? j : insS.length - 1], UnitValue.ZERO, j % 2 == 1); + ins[j] = insSz != null ? insSz : PlatformDefaults.getPanelInsets(j); + } + return ins; + } + } + + /** Parses gaps. + * @param s The string that contains gap information. Should start with "gap". + * @return The gaps as specified in <code>s</code>. Indexed: <code>[top,left,bottom,right][min,pref,max]</code> or + * [before,after][min,pref,max] if <code>oneDim</code> is true. + */ + private static BoundSize[] parseGaps(String s) + { + BoundSize[] ret = new BoundSize[4]; + + int ix = startsWithLenient(s, "gaptop", -1, true); + if (ix > -1) { + s = s.substring(ix).trim(); + ret[0] = parseBoundSize(s, true, false); + return ret; + } + + ix = startsWithLenient(s, "gapleft", -1, true); + if (ix > -1) { + s = s.substring(ix).trim(); + ret[1] = parseBoundSize(s, true, true); + return ret; + } + + ix = startsWithLenient(s, "gapbottom", -1, true); + if (ix > -1) { + s = s.substring(ix).trim(); + ret[2] = parseBoundSize(s, true, false); + return ret; + } + + ix = startsWithLenient(s, "gapright", -1, true); + if (ix > -1) { + s = s.substring(ix).trim(); + ret[3] = parseBoundSize(s, true, true); + return ret; + } + + ix = startsWithLenient(s, "gapbefore", -1, true); + if (ix > -1) { + s = s.substring(ix).trim(); + ret[1] = parseBoundSize(s, true, true); + return ret; + } + + ix = startsWithLenient(s, "gapafter", -1, true); + if (ix > -1) { + s = s.substring(ix).trim(); + ret[3] = parseBoundSize(s, true, true); + return ret; + } + + ix = startsWithLenient(s, new String[] {"gapx", "gapy"}, null, true); + if (ix > -1) { + boolean x = s.charAt(3) == 'x'; + String[] gaps = toTrimmedTokens(s.substring(ix).trim(), ' '); + ret[x ? 1 : 0] = parseBoundSize(gaps[0], true, x); + if (gaps.length > 1) + ret[x ? 3 : 2] = parseBoundSize(gaps[1], true, !x); + return ret; + } + + ix = startsWithLenient(s, "gap ", 1, true); + if (ix > -1) { + String[] gaps = toTrimmedTokens(s.substring(ix).trim(), ' '); + + ret[1] = parseBoundSize(gaps[0], true, true); // left + if (gaps.length > 1) { + ret[3] = parseBoundSize(gaps[1], true, false); // right + if (gaps.length > 2) { + ret[0] = parseBoundSize(gaps[2], true, true); // top + if (gaps.length > 3) + ret[2] = parseBoundSize(gaps[3], true, false); // bottom + } + } + return ret; + } + + throw new IllegalArgumentException("Unknown Gap part: '" + s + "'"); + } + + private static int parseSpan(String s) + { + return s.length() > 0 ? Integer.parseInt(s) : LayoutUtil.INF; + } + + private static Float parseFloat(String s, Float nullVal) + { + return s.length() > 0 ? new Float(Float.parseFloat(s)) : nullVal; + } + + /** Parses a singele "min:pref:max" value. May look something like <code>"10px:20lp:30%"</code> or <code>"pref!"</code>. + * @param s The string to parse. Not <code>null</code>. + * @param isGap If this bound size is a gap (different empty string handling). + * @param isHor If the size is for the horizontal dimension. + * @return A bound size that may be <code>null</code> if the string was "null", "n" or <code>null</code>. + */ + public static BoundSize parseBoundSize(String s, boolean isGap, boolean isHor) + { + if (s.length() == 0 || s.equals("null") || s.equals("n")) + return null; + + boolean push = false; + if (s.endsWith("push")) { + if (isGap == false) + throw new IllegalArgumentException("Only gaps can have 'push' in size. Use as separate keyword for components."); + push = true; + int l = s.length(); + s = s.substring(0, l - (s.endsWith(":push") ? 5 : 4)); + if (s.length() == 0) + return new BoundSize(null, null, null, true, s); + } + + String[] sizes = toTrimmedTokens(s, ':'); + String s0 = sizes[0]; + + if (sizes.length == 1) { + boolean hasEM = s0.endsWith("!"); + if (hasEM) + s0 = s0.substring(0, s0.length() - 1); + UnitValue uv = parseUnitValue(s0, null, isHor); + return new BoundSize(((isGap || hasEM) ? uv : null), uv, (hasEM ? uv : null), push, s); + + } else if (sizes.length == 2) { + return new BoundSize(parseUnitValue(s0, null, isHor), parseUnitValue(sizes[1], null, isHor), null, push, s); + } else if (sizes.length == 3) { + return new BoundSize(parseUnitValue(s0, null, isHor), parseUnitValue(sizes[1], null, isHor), parseUnitValue(sizes[2], null, isHor), push, s); + } else { + throw new IllegalArgumentException("Min:Preferred:Max size section must contain 0, 1 or 2 colons. '" + s + "'"); + } + } + + /** Parses a single unit value that may also be an alignment as parsed by {@link #parseAlignKeywords(String, boolean)}. + * @param s The string to parse. Not <code>null</code>. May look something like <code>"10px"</code> or <code>"5dlu"</code>. + * @param isHor If the value is for the horizontal dimension. + * @param emptyReplacement A replacement if <code>s</code> is empty. May be <code>null</code>. + * @return The parsed unit value. May be <code>null</code>. + */ + public static UnitValue parseUnitValueOrAlign(String s, boolean isHor, UnitValue emptyReplacement) + { + if (s.length() == 0) + return emptyReplacement; + + UnitValue align = parseAlignKeywords(s, isHor); + if (align != null) + return align; + + return parseUnitValue(s, emptyReplacement, isHor); + } + + /** Parses a single unit value. E.g. "10px" or "5in" + * @param s The string to parse. Not <code>null</code>. May look something like <code>"10px"</code> or <code>"5dlu"</code>. + * @param isHor If the value is for the horizontal dimension. + * @return The parsed unit value. <code>null</code> is empty string, + */ + public static UnitValue parseUnitValue(String s, boolean isHor) + { + return parseUnitValue(s, null, isHor); + } + + /** Parses a single unit value. + * @param s The string to parse. May be <code>null</code>. May look something like <code>"10px"</code> or <code>"5dlu"</code>. + * @param emptyReplacement A replacement <code>s</code> is empty or <code>null</code>. May be <code>null</code>. + * @param isHor If the value is for the horizontal dimension. + * @return The parsed unit value. May be <code>null</code>. + */ + private static UnitValue parseUnitValue(String s, UnitValue emptyReplacement, boolean isHor) + { + if (s == null || s.length() == 0) + return emptyReplacement; + + String cs = s; // Save creation string. + char c0 = s.charAt(0); + + // Remove start and end parentheses, if there. + if (c0 == '(' && s.charAt(s.length() - 1) == ')') + s = s.substring(1, s.length() - 1); + + if (c0 == 'n' && (s.equals("null") || s.equals("n"))) + return null; + + if (c0 == 'i' && s.equals("inf")) + return UnitValue.INF; + + int oper = getOper(s); + boolean inline = oper == UnitValue.ADD || oper == UnitValue.SUB || oper == UnitValue.MUL || oper == UnitValue.DIV; + + if (oper != UnitValue.STATIC) { // It is a multi-value + + String[] uvs; + if (inline == false) { // If the format is of type "opr(xxx,yyy)" (compared to in-line "10%+15px") + String sub = s.substring(4, s.length() - 1).trim(); + uvs = toTrimmedTokens(sub, ','); + if (uvs.length == 1) + return parseUnitValue(sub, null, isHor); + } else { + char delim; + if (oper == UnitValue.ADD) { + delim = '+'; + } else if (oper == UnitValue.SUB) { + delim = '-'; + } else if (oper == UnitValue.MUL) { + delim = '*'; + } else { // div left + delim = '/'; + } + uvs = toTrimmedTokens(s, delim); + if (uvs.length > 2) { // More than one +-*/. + String last = uvs[uvs.length - 1]; + String first = s.substring(0, s.length() - last.length() - 1); + uvs = new String[] {first, last}; + } + } + + if (uvs.length != 2) + throw new IllegalArgumentException("Malformed UnitValue: '" + s + "'"); + + UnitValue sub1 = parseUnitValue(uvs[0], null, isHor); + UnitValue sub2 = parseUnitValue(uvs[1], null, isHor); + + if (sub1 == null || sub2 == null) + throw new IllegalArgumentException("Malformed UnitValue. Must be two sub-values: '" + s + "'"); + + return new UnitValue(isHor, oper, sub1, sub2, cs); + } else { + try { + String[] numParts = getNumTextParts(s); + float value = numParts[0].length() > 0 ? Float.parseFloat(numParts[0]) : 1; // e.g. "related" has no number part.. + + return new UnitValue(value, numParts[1], isHor, oper, cs); + + } catch(Exception e) { + throw new IllegalArgumentException("Malformed UnitValue: '" + s + "'"); + } + } + } + + /** Parses alignment keywords and returns the approprieate <code>UnitValue</code>. + * @param s The string to parse. Not <code>null</code>. + * @param isHor If alignments for horizontal is checked. <code>false</code> means vertical. + * @return The unit value or <code>null</code> if not recognized (no exception). + */ + static UnitValue parseAlignKeywords(String s, boolean isHor) + { + if (startsWithLenient(s, "center", 1, false) != -1) + return UnitValue.CENTER; + + if (isHor) { + if (startsWithLenient(s, "left", 1, false) != -1) + return UnitValue.LEFT; + + if (startsWithLenient(s, "right", 1, false) != -1) + return UnitValue.RIGHT; + + if (startsWithLenient(s, "leading", 4, false) != -1) + return UnitValue.LEADING; + + if (startsWithLenient(s, "trailing", 5, false) != -1) + return UnitValue.TRAILING; + + if (startsWithLenient(s, "label", 5, false) != -1) + return UnitValue.LABEL; + + } else { + + if (startsWithLenient(s, "baseline", 4, false) != -1) + return UnitValue.BASELINE_IDENTITY; + + if (startsWithLenient(s, "top", 1, false) != -1) + return UnitValue.TOP; + + if (startsWithLenient(s, "bottom", 1, false) != -1) + return UnitValue.BOTTOM; + } + + return null; + } + + /** Splits a text-number combination such as "hello 10.0" into <code>{"hello", "10.0"}</code>. + * @param s The string to split. Not <code>null</code>. Needs be be resonably formatted since the method + * only finds the first 0-9 or . and cuts the string in half there. + * @return Always length 2 and no <code>null</code> elements. Elements are "" if no part found. + */ + private static String[] getNumTextParts(String s) + { + for (int i = 0, iSz = s.length(); i < iSz; i++) { + char c = s.charAt(i); + if (c == ' ') + throw new IllegalArgumentException("Space in UnitValue: '" + s + "'"); + + if ((c < '0' || c > '9') && c != '.' && c != '-') + return new String[] {s.substring(0, i).trim(), s.substring(i).trim()}; + } + return new String[] {s, ""}; + } + + /** Returns the operation depending on the start character. + * @param s The string to check. Not <code>null</code>. + * @return E.g. UnitValue.ADD, UnitValue.SUB or UnitValue.STATIC. Returns negative value for in-line operations. + */ + private static int getOper(String s) + { + int len = s.length(); + if (len < 3) + return UnitValue.STATIC; + + if (len > 5 && s.charAt(3) == '(' && s.charAt(len - 1) == ')') { + if (s.startsWith("min(")) + return UnitValue.MIN; + + if (s.startsWith("max(")) + return UnitValue.MAX; + + if (s.startsWith("mid(")) + return UnitValue.MID; + } + + // Try in-line add/sub. E.g. "pref+10px". + for (int j = 0; j < 2; j++) { // First +- then */ (precedence) + for (int i = len - 1, p = 0; i > 0; i--) { + char c = s.charAt(i); + if (c == ')') { + p++; + } else if (c == '(') { + p--; + } else if (p == 0) { + if (j == 0) { + if (c == '+') + return UnitValue.ADD; + if (c == '-') + return UnitValue.SUB; + } else { + if (c == '*') + return UnitValue.MUL; + if (c == '/') + return UnitValue.DIV; + } + } + } + } + return UnitValue.STATIC; + } + + /** Returns if a string shares at least a specified numbers starting characters with a number of matches. + * <p> + * This method just excercises {@link #startsWithLenient(String, String, int, boolean)} with every one of + * <code>matches</code> and <code>minChars</code>. + * @param s The string to check. Not <code>null</code>. + * @param matches A number of possible starts for <code>s</code>. + * @param minChars The mimimum number of characters to match for every element in <code>matches</code>. Needs + * to be of same length as <code>matches</code>. Can be <code>null</code>. + * @param acceptTrailing If after the required number of charecters are matched onrecognized characters that are not + * in one of the the <code>matches</code> string should be accepted. For instance if "abczz" should be matched with + * "abcdef" and min chars 3. + * @return The index of the first unmatched character if <code>minChars</code> was reached or <code>-1</code> if a match was not + * found. + */ + private static int startsWithLenient(String s, String[] matches, int[] minChars, boolean acceptTrailing) + { + for (int i = 0; i < matches.length; i++) { + int minChar = minChars != null ? minChars[i] : -1; + int ix = startsWithLenient(s, matches[i], minChar, acceptTrailing); + if (ix > -1) + return ix; + } + return -1; + } + + /** Returns if a string shares at least a specified numbers starting characters with a match. + * @param s The string to check. Not <code>null</code> and must be trimmed. + * @param match The possible start for <code>s</code>. Not <code>null</code> and must be trimmed. + * @param minChars The mimimum number of characters to match to <code>s</code> for it this to be considered a match. -1 means + * the full length of <code>match</code>. + * @param acceptTrailing If after the required number of charecters are matched unrecognized characters that are not + * in one of the the <code>matches</code> string should be accepted. For instance if "abczz" should be matched with + * "abcdef" and min chars 3. + * @return The index of the first unmatched character if <code>minChars</code> was reached or <code>-1</code> if a match was not + * found. + */ + private static int startsWithLenient(String s, String match, int minChars, boolean acceptTrailing) + { + if (s.charAt(0) != match.charAt(0)) // Fast sanity check. + return -1; + + if (minChars == -1) + minChars = match.length(); + + int sSz = s.length(); + if (sSz < minChars) + return -1; + + int mSz = match.length(); + int sIx = 0; + for (int mIx = 0; mIx < mSz; sIx++, mIx++) { + while (sIx < sSz && (s.charAt(sIx) == ' ' || s.charAt(sIx) == '_')) // Disregard spaces and _ + sIx++; + + if (sIx >= sSz || s.charAt(sIx) != match.charAt(mIx)) + return mIx >= minChars && (acceptTrailing || sIx >= sSz) && (sIx >= sSz || s.charAt(sIx - 1) == ' ') ? sIx : -1; + } +// return (sIx >= sSz || acceptTrailing) && (sIx >= sSz || s.charAt(sIx) == ' ') ? sIx : -1; + return sIx >= sSz || acceptTrailing ||s.charAt(sIx) == ' ' ? sIx : -1; + } + + /** Parses a string and returns it in those parts of the string that are separated with a <code>sep</code> character. + * <p> + * separator characters within parentheses will not be counted or handled in any way, whatever the depth. + * @param s The string to parse. If it starts and/or ends with a <code>sep</code> the first and/or last element returned will be "". If + * two <code>sep</code> are next to eachother and empty element will be "between" the periods. The <code>sep</code> themselves will never be returned. + * @param sep The separator char. + * @return Those parts of the string that are separated with <code>sep</code>. Never null and at least of size 1 + */ + private final static String[] toTrimmedTokens(String s, char sep) + { + int toks = 0, sSize = s.length(); + + // Count the sep:s + int p = 0; + for(int i = 0; i < sSize; i++) { + char c = s.charAt(i); + if (c == '(') { + p++; + } else if (c == ')') { + p--; + } else if (p == 0 && c == sep) { + toks++; + } + if (p < 0) + throw new IllegalArgumentException("Unbalanced parentheses: '" + s + "'"); + } + if (p != 0) + throw new IllegalArgumentException("Unbalanced parentheses: '" + s + "'"); + + if (toks == 0) + return new String [] {s.trim()}; + + String[] retArr = new String[toks + 1]; + + int st = 0, pNr = 0; + p = 0; + for (int i = 0; i < sSize; i++) { + + char c = s.charAt(i); + if (c == '(') { + p++; + } else if (c == ')') { + p--; + } else if (p == 0 && c == sep) { + retArr[pNr++] = s.substring(st, i).trim(); + st = i + 1; + } + } + + retArr[pNr++] = s.substring(st, sSize).trim(); + return retArr; + } + + /** Parses "AAA[BBB]CCC[DDD]EEE" into {"AAA", "BBB", "CCC", "DDD", "EEE", "FFF"}. Handles empty parts. Will always start and end outside + * a [] block so that the number of returned elemets will always be uneven and at least of length 3. + * <p> + * "|" is interprated as "][". + * @param s The string. Might be "" but not null. Should be trimmed. + * @return The string divided into elements. Never <code>null</code> and at least of length 3. + * @throws IllegalArgumentException If a [] mismatch of some kind. (If not same [ as ] count or if the interleave.) + */ + private final static ArrayList<String> getRowColAndGapsTrimmed(String s) + { + if (s.indexOf('|') != -1) + s = s.replaceAll("\\|", "]["); + + ArrayList<String> retList = new ArrayList<String>(Math.max(s.length() >> 2 + 1, 3)); // Aprox return length. + int s0 = 0, s1 = 0; // '[' and ']' count. + int st = 0; // Start of "next token to add". + for (int i = 0, iSz = s.length(); i < iSz; i++) { + char c = s.charAt(i); + if (c == '[') { + s0++; + } else if (c == ']') { + s1++; + } else { + continue; + } + + if (s0 != s1 && (s0 - 1) != s1) + break; // Wrong [ or ] found. Break for throw. + + retList.add(s.substring(st, i).trim()); + st = i + 1; + } + if (s0 != s1) + throw new IllegalArgumentException("'[' and ']' mismatch in row/column format string: " + s); + + if (s0 == 0) { + retList.add(""); + retList.add(s); + retList.add(""); + } else if (retList.size() % 2 == 0) { + retList.add(s.substring(st, s.length())); + } + + return retList; + } + + /** Makes <code>null</code> "", trimms and converts to lower case. + * @param s The string + * @return Not null. + */ + public static final String prepare(String s) + { + return s != null ? s.trim().toLowerCase() : ""; + } + +// /** Tests to serialize and deserialize the object with both XMLEncoder/Decoder and through Serializable +// * @param o The object to serialize +// * @return The same object after a tri through the process. +// */ +// public static final Object serializeTest(Object o) +// { +// try { +// ByteArrayOutputStream barr = new ByteArrayOutputStream(); +// XMLEncoder enc = new XMLEncoder(barr); +// enc.writeObject(o); +// enc.close(); +// +// XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(barr.toByteArray())); +// o = dec.readObject(); +// dec.close(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// try { +// ByteArrayOutputStream barr = new ByteArrayOutputStream(); +// ObjectOutputStream oos = new ObjectOutputStream(barr); +// oos.writeObject(o); +// oos.close(); +// +// ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray())); +// o = ois.readObject(); +// ois.close(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// return o; +// } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/ContainerWrapper.java b/prototypes/miglayout/net/miginfocom/layout/ContainerWrapper.java index 65428add..8f801705 100644 --- a/prototypes/miglayout/net/miginfocom/layout/ContainerWrapper.java +++ b/prototypes/miglayout/net/miginfocom/layout/ContainerWrapper.java @@ -1,69 +1,69 @@ -package net.miginfocom.layout;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** A class that wraps a container that contains components.
- */
-public interface ContainerWrapper extends ComponentWrapper
-{
- /** Returns the components of the container that wrapper is wrapping.
- * @return The components of the container that wrapper is wrapping. Never <code>null</code>.
- */
- public abstract ComponentWrapper[] getComponents();
-
- /** Returns the number of components that this parent has.
- * @return The number of components that this parent has.
- */
- public abstract int getComponentCount();
-
- /** Returns the <code>LayoutHandler</code> (in Swing terms) that is handling the layout of this container.
- * If there exist no such class the method should return the same as {@link #getComponent()}, which is the
- * container itself.
- * @return The layout handler instance. Never <code>null</code>.
- */
- public abstract Object getLayout();
-
- /** Returns if this container is using left-to-right component ordering.
- * @return If this container is using left-to-right component ordering.
- */
- public abstract boolean isLeftToRight();
-
- /** Paints a cell to indicate where it is.
- * @param x The x coordinate to start the drwaing.
- * @param y The x coordinate to start the drwaing.
- * @param width The width to draw/fill
- * @param height The height to draw/fill
- */
- public abstract void paintDebugCell(int x, int y, int width, int height);
-}
+package net.miginfocom.layout; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** A class that wraps a container that contains components. + */ +public interface ContainerWrapper extends ComponentWrapper +{ + /** Returns the components of the container that wrapper is wrapping. + * @return The components of the container that wrapper is wrapping. Never <code>null</code>. + */ + public abstract ComponentWrapper[] getComponents(); + + /** Returns the number of components that this parent has. + * @return The number of components that this parent has. + */ + public abstract int getComponentCount(); + + /** Returns the <code>LayoutHandler</code> (in Swing terms) that is handling the layout of this container. + * If there exist no such class the method should return the same as {@link #getComponent()}, which is the + * container itself. + * @return The layout handler instance. Never <code>null</code>. + */ + public abstract Object getLayout(); + + /** Returns if this container is using left-to-right component ordering. + * @return If this container is using left-to-right component ordering. + */ + public abstract boolean isLeftToRight(); + + /** Paints a cell to indicate where it is. + * @param x The x coordinate to start the drwaing. + * @param y The x coordinate to start the drwaing. + * @param width The width to draw/fill + * @param height The height to draw/fill + */ + public abstract void paintDebugCell(int x, int y, int width, int height); +} diff --git a/prototypes/miglayout/net/miginfocom/layout/DimConstraint.java b/prototypes/miglayout/net/miginfocom/layout/DimConstraint.java index 47c1021c..a5b1276d 100644 --- a/prototypes/miglayout/net/miginfocom/layout/DimConstraint.java +++ b/prototypes/miglayout/net/miginfocom/layout/DimConstraint.java @@ -1,466 +1,466 @@ -package net.miginfocom.layout;
-
-import java.io.*;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** A simple value holder for a constraint for one dimension.
- */
-public final class DimConstraint implements Externalizable
-{
- /** How this entity can be resized in the dimension that this constraint represents.
- */
- final ResizeConstraint resize = new ResizeConstraint();
-
- // Look at the properties' getter/setter methods for exmplanation
-
- private String sizeGroup = null; // A "context" compared with equals.
-
- private BoundSize size = null; // Min, pref, max. May be null.
-
- private BoundSize gapBefore = null, gapAfter = null;
-
- private UnitValue align = null;
-
-
- // ************** Only applicable on components! *******************
-
- private String endGroup = null; // A "context" compared with equals.
-
-
- // ************** Only applicable on rows/columns! *******************
-
- private boolean fill = false;
-
- private boolean noGrid = false;
-
- /** Empty constructor.
- */
- public DimConstraint()
- {
- }
-
- /** Returns the grow priority. Relative priority is used for determining which entities gets the extra space first.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The grow priority.
- */
- public int getGrowPriority()
- {
- return resize.growPrio;
- }
-
- /** Sets the grow priority. Relative priority is used for determining which entities gets the extra space first.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The new grow priority.
- */
- public void setGrowPriority(int p)
- {
- resize.growPrio = p;
- }
-
- /** Returns the grow weight.<p>
- * Grow weight is how flexilble the entity should be, relative to other entities, when it comes to growing. <code>null</code> or
- * zero mean it will never grow. An entity that has twise the grow weight compared to another entity will get twice
- * as much of available space.
- * <p>
- * GrowWeight are only compared within the same GrowPrio.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current grow weight.
- */
- public Float getGrow()
- {
- return resize.grow;
- }
-
- /** Sets the grow weight.<p>
- * Grow weight is how flexilble the entity should be, relative to other entities, when it comes to growing. <code>null</code> or
- * zero mean it will never grow. An entity that has twise the grow weight compared to another entity will get twice
- * as much of available space.
- * <p>
- * GrowWeight are only compared within the same GrowPrio.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param weight The new grow weight.
- */
- public void setGrow(Float weight)
- {
- resize.grow = weight;
- }
-
- /** Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarse.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The shrink priority.
- */
- public int getShrinkPriority()
- {
- return resize.shrinkPrio;
- }
-
- /** Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarse.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param p The new shrink priority.
- */
- public void setShrinkPriority(int p)
- {
- resize.shrinkPrio = p;
- }
-
- /** Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarse.
- * Shrink weight is how flexilble the entity should be, relative to other entities, when it comes to shrinking. <code>null</code> or
- * zero mean it will never shrink (default). An entity that has twise the shrink weight compared to another entity will get twice
- * as much of available space.
- * <p>
- * Shrink(Weight) are only compared within the same ShrinkPrio.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current shrink weight.
- */
- public Float getShrink()
- {
- return resize.shrink;
- }
-
- /** Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarse.
- * Shrink weight is how flexilble the entity should be, relative to other entities, when it comes to shrinking. <code>null</code> or
- * zero mean it will never shrink (default). An entity that has twise the shrink weight compared to another entity will get twice
- * as much of available space.
- * <p>
- * Shrink(Weight) are only compared within the same ShrinkPrio.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param weight The new shrink weight.
- */
- public void setShrink(Float weight)
- {
- resize.shrink = weight;
- }
-
- public UnitValue getAlignOrDefault(boolean isCols)
- {
- if (align != null)
- return align;
-
- return isCols ? UnitValue.LEADING : UnitValue.CENTER;
- }
-
- /** Returns the alignment used either as a default value for sub-entities or for this entity.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The alignment.
- */
- public UnitValue getAlign()
- {
- return align;
- }
-
- /** Sets the alignment used wither as a default value for sub-entities or for this entity.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param uv The new shrink priority. E.g. {@link UnitValue#CENTER} or {@link net.miginfocom.layout.UnitValue#LEADING}.
- */
- public void setAlign(UnitValue uv)
- {
- this.align = uv;
- }
-
- /** Returns the gap after this entitiy. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
- * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The gap after this entitiy
- */
- public BoundSize getGapAfter()
- {
- return gapAfter;
- }
-
- /** Sets the gap after this entitiy. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
- * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The new gap.
- * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean).
- */
- public void setGapAfter(BoundSize size)
- {
- this.gapAfter = size;
- }
-
- boolean hasGapAfter()
- {
- return gapAfter != null && gapAfter.isUnset() == false;
- }
-
- boolean isGapAfterPush()
- {
- return gapAfter != null && gapAfter.getGapPush();
- }
-
- /** Returns the gap before this entitiy. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
- * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The gap before this entitiy
- */
- public BoundSize getGapBefore()
- {
- return gapBefore;
- }
-
- /** Sets the gap before this entitiy. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and
- * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The new gap.
- * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean).
- */
- public void setGapBefore(BoundSize size)
- {
- this.gapBefore = size;
- }
-
- boolean hasGapBefore()
- {
- return gapBefore != null && gapBefore.isUnset() == false;
- }
-
- boolean isGapBeforePush()
- {
- return gapBefore != null && gapBefore.getGapPush();
- }
-
- /** Returns the min/prerefferd/max size for the entity in the dimension that this object describes.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current size. May be <code>null</code>.
- * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean).
- */
- public BoundSize getSize()
- {
- return size;
- }
-
- /** Sets the min/prerefferd/max size for the eintity in the dimension that this object describes.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param size The new size. May be <code>null</code>.
- */
- public void setSize(BoundSize size)
- {
- this.size = size;
- }
-
- /** Returns the size group that this entitiy should be in for the demension that this object is describing.
- * If this constraint is in a size group that is specified here. <code>null</code> means no size group
- * and all other values are legal. Comparison with .equals(). Components/columnss/rows in the same size group
- * will have the same min/preferred/max size; that of the largest in the group for the first two and the
- * smallest for max.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current size group. May be <code>null</code>.
- */
- public String getSizeGroup()
- {
- return sizeGroup;
- }
-
- /** Sets the size group that this entitiy should be in for the demension that this object is describing.
- * If this constraint is in a size group that is specified here. <code>null</code> means no size group
- * and all other values are legal. Comparison with .equals(). Components/columnss/rows in the same size group
- * will have the same min/preferred/max size; that of the largest in the group for the first two and the
- * smallest for max.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s The new size group. <code>null</code> disables size grouping.
- */
- public void setSizeGroup(String s)
- {
- sizeGroup = s;
- }
-
- // ************** Only applicable on components ! *******************
-
- /** Returns the end group that this entitiy should be in for the demension that this object is describing.
- * If this constraint is in an end group that is specified here. <code>null</code> means no end group
- * and all other values are legal. Comparison with .equals(). Components in the same end group
- * will have the same end coordinate.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return The current end group. <code>null</code> may be returned.
- */
- public String getEndGroup()
- {
- return endGroup;
- }
-
- /** Sets the end group that this entitiy should be in for the demension that this object is describing.
- * If this constraint is in an end group that is specified here. <code>null</code> means no end group
- * and all other values are legal. Comparison with .equals(). Components in the same end group
- * will have the same end coordinate.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s The new end group. <code>null</code> disables end grouping.
- */
- public void setEndGroup(String s)
- {
- endGroup = s;
- }
-
- // ************** Not applicable on components below ! *******************
-
- /** Returns if the component in the row/column that this constraint should default be grown in the same dimension that
- * this constraint represents (width for column and height for a row).
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return code>true</code> means that components should grow.
- */
- public boolean isFill()
- {
- return fill;
- }
-
- /** Sets if the component in the row/column that this constraint should default be grown in the same dimension that
- * this constraint represents (width for column and height for a row).
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param b <code>true</code> means that components should grow.
- */
- public void setFill(boolean b)
- {
- fill = b;
- }
-
- /** Returns if the row/column should default to flow and not to grid behaviour. This means that the whole row/column
- * will be one cell and all components will end up in that cell.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>true</code> means that the whole row/column should be one cell.
- */
- public boolean isNoGrid()
- {
- return noGrid;
- }
-
- /** Sets if the row/column should default to flow and not to grid behaviour. This means that the whole row/column
- * will be one cell and all components will end up in that cell.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param b <code>true</code> means that the whole row/column should be one cell.
- */
- public void setNoGrid(boolean b)
- {
- this.noGrid = b;
- }
-
- /** Returns the gaps as pixel values.
- * @param parent The parent. Used to get the pixel values.
- * @param defGap The default gap to use if there is no gap set on this object (i.e. it is null).
- * @param refSize The reference size used to get the pixel sizes.
- * @param before IF it is the gap before rather than the gap after to return.
- * @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtil#NOT_SET}
- * for gap sizes that are <code>null</code>. Returns <code>null</code> if there was no gap specified. A new and free to use array.
- */
- int[] getRowGaps(ContainerWrapper parent, BoundSize defGap, int refSize, boolean before)
- {
- BoundSize gap = before ? gapBefore : gapAfter;
- if (gap == null || gap.isUnset())
- gap = defGap;
-
- if (gap == null || gap.isUnset())
- return null;
-
- int[] ret = new int[3];
- for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) {
- UnitValue uv = gap.getSize(i);
- ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtil.NOT_SET;
- }
- return ret;
- }
-
- /** Returns the gaps as pixel values.
- * @param parent The parent. Used to get the pixel values.
- * @param comp The component that the gap is for. If not for a component it is <code>null</code>.
- * @param adjGap The gap that the adjacent component, if any, has towards <code>comp</code>.
- * @param adjacentComp The adjacent component if any. May be <code>null</code>.
- * @param refSize The reference size used to get the pixel sizes.
- * @param adjacentSide Whan side the <code>adjacentComp</code> is on. 0 = top, 1 = left, 2 = bottom, 3 = right.
- * @param tag The tag string that the component might be tagged with in the component constraints. May be <code>null</code>.
- * @param isLTR If it is left-to-right.
- * @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtil#NOT_SET}
- * for gap sizes that are <code>null</code>. Returns <code>null</code> if there was no gap specified. A new and free to use array.
- */
- int[] getComponentGaps(ContainerWrapper parent, ComponentWrapper comp, BoundSize adjGap, ComponentWrapper adjacentComp, String tag, int refSize, int adjacentSide, boolean isLTR)
- {
- BoundSize gap = adjacentSide < 2 ? gapBefore : gapAfter;
-
- boolean hasGap = gap != null && gap.getGapPush();
- if ((gap == null || gap.isUnset()) && (adjGap == null || adjGap.isUnset()) && comp != null)
- gap = PlatformDefaults.getDefaultComponentGap(comp, adjacentComp, adjacentSide + 1, tag, isLTR);
-
- if (gap == null)
- return hasGap ? new int[] {0, 0, LayoutUtil.NOT_SET} : null;
-
- int[] ret = new int[3];
- for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) {
- UnitValue uv = gap.getSize(i);
- ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtil.NOT_SET;
- }
- return ret;
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
-
- public void writeExternal(ObjectOutput out) throws IOException
- {
- if (getClass() == DimConstraint.class)
- LayoutUtil.writeAsXML(out, this);
- }
-}
+package net.miginfocom.layout; + +import java.io.*; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** A simple value holder for a constraint for one dimension. + */ +public final class DimConstraint implements Externalizable +{ + /** How this entity can be resized in the dimension that this constraint represents. + */ + final ResizeConstraint resize = new ResizeConstraint(); + + // Look at the properties' getter/setter methods for exmplanation + + private String sizeGroup = null; // A "context" compared with equals. + + private BoundSize size = null; // Min, pref, max. May be null. + + private BoundSize gapBefore = null, gapAfter = null; + + private UnitValue align = null; + + + // ************** Only applicable on components! ******************* + + private String endGroup = null; // A "context" compared with equals. + + + // ************** Only applicable on rows/columns! ******************* + + private boolean fill = false; + + private boolean noGrid = false; + + /** Empty constructor. + */ + public DimConstraint() + { + } + + /** Returns the grow priority. Relative priority is used for determining which entities gets the extra space first. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The grow priority. + */ + public int getGrowPriority() + { + return resize.growPrio; + } + + /** Sets the grow priority. Relative priority is used for determining which entities gets the extra space first. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The new grow priority. + */ + public void setGrowPriority(int p) + { + resize.growPrio = p; + } + + /** Returns the grow weight.<p> + * Grow weight is how flexilble the entity should be, relative to other entities, when it comes to growing. <code>null</code> or + * zero mean it will never grow. An entity that has twise the grow weight compared to another entity will get twice + * as much of available space. + * <p> + * GrowWeight are only compared within the same GrowPrio. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current grow weight. + */ + public Float getGrow() + { + return resize.grow; + } + + /** Sets the grow weight.<p> + * Grow weight is how flexilble the entity should be, relative to other entities, when it comes to growing. <code>null</code> or + * zero mean it will never grow. An entity that has twise the grow weight compared to another entity will get twice + * as much of available space. + * <p> + * GrowWeight are only compared within the same GrowPrio. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param weight The new grow weight. + */ + public void setGrow(Float weight) + { + resize.grow = weight; + } + + /** Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarse. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The shrink priority. + */ + public int getShrinkPriority() + { + return resize.shrinkPrio; + } + + /** Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarse. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param p The new shrink priority. + */ + public void setShrinkPriority(int p) + { + resize.shrinkPrio = p; + } + + /** Returns the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarse. + * Shrink weight is how flexilble the entity should be, relative to other entities, when it comes to shrinking. <code>null</code> or + * zero mean it will never shrink (default). An entity that has twise the shrink weight compared to another entity will get twice + * as much of available space. + * <p> + * Shrink(Weight) are only compared within the same ShrinkPrio. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current shrink weight. + */ + public Float getShrink() + { + return resize.shrink; + } + + /** Sets the shrink priority. Relative priority is used for determining which entities gets smaller first when space is scarse. + * Shrink weight is how flexilble the entity should be, relative to other entities, when it comes to shrinking. <code>null</code> or + * zero mean it will never shrink (default). An entity that has twise the shrink weight compared to another entity will get twice + * as much of available space. + * <p> + * Shrink(Weight) are only compared within the same ShrinkPrio. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param weight The new shrink weight. + */ + public void setShrink(Float weight) + { + resize.shrink = weight; + } + + public UnitValue getAlignOrDefault(boolean isCols) + { + if (align != null) + return align; + + return isCols ? UnitValue.LEADING : UnitValue.CENTER; + } + + /** Returns the alignment used either as a default value for sub-entities or for this entity. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The alignment. + */ + public UnitValue getAlign() + { + return align; + } + + /** Sets the alignment used wither as a default value for sub-entities or for this entity. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param uv The new shrink priority. E.g. {@link UnitValue#CENTER} or {@link net.miginfocom.layout.UnitValue#LEADING}. + */ + public void setAlign(UnitValue uv) + { + this.align = uv; + } + + /** Returns the gap after this entitiy. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and + * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The gap after this entitiy + */ + public BoundSize getGapAfter() + { + return gapAfter; + } + + /** Sets the gap after this entitiy. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and + * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The new gap. + * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean). + */ + public void setGapAfter(BoundSize size) + { + this.gapAfter = size; + } + + boolean hasGapAfter() + { + return gapAfter != null && gapAfter.isUnset() == false; + } + + boolean isGapAfterPush() + { + return gapAfter != null && gapAfter.getGapPush(); + } + + /** Returns the gap before this entitiy. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and + * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The gap before this entitiy + */ + public BoundSize getGapBefore() + { + return gapBefore; + } + + /** Sets the gap before this entitiy. The gap is an empty space and can have a min/preferred/maximum size so that it can shrink and + * grow depending on available space. Gaps are against other entities' edges and not against other entities' gaps. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The new gap. + * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean). + */ + public void setGapBefore(BoundSize size) + { + this.gapBefore = size; + } + + boolean hasGapBefore() + { + return gapBefore != null && gapBefore.isUnset() == false; + } + + boolean isGapBeforePush() + { + return gapBefore != null && gapBefore.getGapPush(); + } + + /** Returns the min/prerefferd/max size for the entity in the dimension that this object describes. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current size. May be <code>null</code>. + * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean). + */ + public BoundSize getSize() + { + return size; + } + + /** Sets the min/prerefferd/max size for the eintity in the dimension that this object describes. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param size The new size. May be <code>null</code>. + */ + public void setSize(BoundSize size) + { + this.size = size; + } + + /** Returns the size group that this entitiy should be in for the demension that this object is describing. + * If this constraint is in a size group that is specified here. <code>null</code> means no size group + * and all other values are legal. Comparison with .equals(). Components/columnss/rows in the same size group + * will have the same min/preferred/max size; that of the largest in the group for the first two and the + * smallest for max. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current size group. May be <code>null</code>. + */ + public String getSizeGroup() + { + return sizeGroup; + } + + /** Sets the size group that this entitiy should be in for the demension that this object is describing. + * If this constraint is in a size group that is specified here. <code>null</code> means no size group + * and all other values are legal. Comparison with .equals(). Components/columnss/rows in the same size group + * will have the same min/preferred/max size; that of the largest in the group for the first two and the + * smallest for max. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s The new size group. <code>null</code> disables size grouping. + */ + public void setSizeGroup(String s) + { + sizeGroup = s; + } + + // ************** Only applicable on components ! ******************* + + /** Returns the end group that this entitiy should be in for the demension that this object is describing. + * If this constraint is in an end group that is specified here. <code>null</code> means no end group + * and all other values are legal. Comparison with .equals(). Components in the same end group + * will have the same end coordinate. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return The current end group. <code>null</code> may be returned. + */ + public String getEndGroup() + { + return endGroup; + } + + /** Sets the end group that this entitiy should be in for the demension that this object is describing. + * If this constraint is in an end group that is specified here. <code>null</code> means no end group + * and all other values are legal. Comparison with .equals(). Components in the same end group + * will have the same end coordinate. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s The new end group. <code>null</code> disables end grouping. + */ + public void setEndGroup(String s) + { + endGroup = s; + } + + // ************** Not applicable on components below ! ******************* + + /** Returns if the component in the row/column that this constraint should default be grown in the same dimension that + * this constraint represents (width for column and height for a row). + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return code>true</code> means that components should grow. + */ + public boolean isFill() + { + return fill; + } + + /** Sets if the component in the row/column that this constraint should default be grown in the same dimension that + * this constraint represents (width for column and height for a row). + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param b <code>true</code> means that components should grow. + */ + public void setFill(boolean b) + { + fill = b; + } + + /** Returns if the row/column should default to flow and not to grid behaviour. This means that the whole row/column + * will be one cell and all components will end up in that cell. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>true</code> means that the whole row/column should be one cell. + */ + public boolean isNoGrid() + { + return noGrid; + } + + /** Sets if the row/column should default to flow and not to grid behaviour. This means that the whole row/column + * will be one cell and all components will end up in that cell. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param b <code>true</code> means that the whole row/column should be one cell. + */ + public void setNoGrid(boolean b) + { + this.noGrid = b; + } + + /** Returns the gaps as pixel values. + * @param parent The parent. Used to get the pixel values. + * @param defGap The default gap to use if there is no gap set on this object (i.e. it is null). + * @param refSize The reference size used to get the pixel sizes. + * @param before IF it is the gap before rather than the gap after to return. + * @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtil#NOT_SET} + * for gap sizes that are <code>null</code>. Returns <code>null</code> if there was no gap specified. A new and free to use array. + */ + int[] getRowGaps(ContainerWrapper parent, BoundSize defGap, int refSize, boolean before) + { + BoundSize gap = before ? gapBefore : gapAfter; + if (gap == null || gap.isUnset()) + gap = defGap; + + if (gap == null || gap.isUnset()) + return null; + + int[] ret = new int[3]; + for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) { + UnitValue uv = gap.getSize(i); + ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtil.NOT_SET; + } + return ret; + } + + /** Returns the gaps as pixel values. + * @param parent The parent. Used to get the pixel values. + * @param comp The component that the gap is for. If not for a component it is <code>null</code>. + * @param adjGap The gap that the adjacent component, if any, has towards <code>comp</code>. + * @param adjacentComp The adjacent component if any. May be <code>null</code>. + * @param refSize The reference size used to get the pixel sizes. + * @param adjacentSide Whan side the <code>adjacentComp</code> is on. 0 = top, 1 = left, 2 = bottom, 3 = right. + * @param tag The tag string that the component might be tagged with in the component constraints. May be <code>null</code>. + * @param isLTR If it is left-to-right. + * @return The [min,preferred,max] sizes for the specified gap. Uses {@link net.miginfocom.layout.LayoutUtil#NOT_SET} + * for gap sizes that are <code>null</code>. Returns <code>null</code> if there was no gap specified. A new and free to use array. + */ + int[] getComponentGaps(ContainerWrapper parent, ComponentWrapper comp, BoundSize adjGap, ComponentWrapper adjacentComp, String tag, int refSize, int adjacentSide, boolean isLTR) + { + BoundSize gap = adjacentSide < 2 ? gapBefore : gapAfter; + + boolean hasGap = gap != null && gap.getGapPush(); + if ((gap == null || gap.isUnset()) && (adjGap == null || adjGap.isUnset()) && comp != null) + gap = PlatformDefaults.getDefaultComponentGap(comp, adjacentComp, adjacentSide + 1, tag, isLTR); + + if (gap == null) + return hasGap ? new int[] {0, 0, LayoutUtil.NOT_SET} : null; + + int[] ret = new int[3]; + for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) { + UnitValue uv = gap.getSize(i); + ret[i] = uv != null ? uv.getPixels(refSize, parent, null) : LayoutUtil.NOT_SET; + } + return ret; + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + if (getClass() == DimConstraint.class) + LayoutUtil.writeAsXML(out, this); + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/Grid.java b/prototypes/miglayout/net/miginfocom/layout/Grid.java index c45ce398..3c19254c 100644 --- a/prototypes/miglayout/net/miginfocom/layout/Grid.java +++ b/prototypes/miglayout/net/miginfocom/layout/Grid.java @@ -1,2245 +1,2245 @@ -package net.miginfocom.layout;
-
-
-import java.util.*;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** Holds components in a grid. Does most of the logic behind the layout manager.
- */
-public final class Grid
-{
- public static final boolean TEST_GAPS = true;
-
- private static final Float[] GROW_100 = new Float[] {ResizeConstraint.WEIGHT_100};
-
- private static final DimConstraint DOCK_DIM_CONSTRAINT = new DimConstraint();
- static {
- DOCK_DIM_CONSTRAINT.setGrowPriority(0);
- }
-
- /** This is the maximum grid position for "normal" components. Docking components use the space out to
- * <code>MAX_DOCK_GRID</code> and below 0.
- */
- private static final int MAX_GRID = 30000;
-
- /** Docking components will use the grid coordinates <code>-MAX_DOCK_GRID -> 0</code> and <code>MAX_GRID -> MAX_DOCK_GRID</code>.
- */
- private static final int MAX_DOCK_GRID = 32767;
-
- /** A constraint used for gaps.
- */
- private static final ResizeConstraint GAP_RC_CONST = new ResizeConstraint(200, ResizeConstraint.WEIGHT_100, 50, null);
- private static final ResizeConstraint GAP_RC_CONST_PUSH = new ResizeConstraint(200, ResizeConstraint.WEIGHT_100, 50, ResizeConstraint.WEIGHT_100);
-
- /** The constraints. Never <code>null</code>.
- */
- private final LC lc;
-
- /** The parent that is layout out and this grid is done for. Never <code>null</code>.
- */
- private final ContainerWrapper container;
-
- /** An x, y array implemented as a sparse array to accomodate for any grid size without wasting memory (or rather 15 bit (0-MAX_GRID * 0-MAX_GRID).
- */
- private final LinkedHashMap<Integer, Cell> grid = new LinkedHashMap<Integer, Cell>(); // [(y << 16) + x] -> Cell. null key for absolute positioned compwraps
-
- private HashMap<Integer, BoundSize> wrapGapMap = null; // Row or Column index depending in the dimension that "raps". Normally row indexes but may be column indexes if "flowy". 0 means before first row/col.
-
- /** The size of the grid. Row count and column count.
- */
- private final TreeSet<Integer> rowIndexes = new TreeSet<Integer>(), colIndexes = new TreeSet<Integer>();
-
- /** The row and column specifications.
- */
- private final AC rowConstr, colConstr;
-
- /** The in the constructor calculated min/pref/max sizes of the rows and columns.
- */
- private FlowSizeSpec colFlowSpecs = null, rowFlowSpecs = null;
-
- /** Components that are connectione in one dimension (such as baseline alignment for instance) are grouped together and stored here.
- * One for each row/column.
- */
- private ArrayList<LinkedDimGroup>[] colGroupLists, rowGroupLists; //[(start)row/col number]
-
- /** The in the constructor calculated min/pref/max size of the whole grid.
- */
- private int[] width = null, height = null;
-
- /** If debug is on contains the bounds for things to paint when calling {@link ContainerWrapper#paintDebugCell(int, int, int, int)}
- */
- private ArrayList<int[]> debugRects = null; // [x, y, width, height]
-
- /** If any of the absolute coordinates for component bounds has links the name of the target is in this Set.
- * Since it requires some memory and computations this is checked at the creation so that
- * the link information is only created if needed later.
- * <p>
- * The boolean is true for groups id:s and null for normal id:s.
- */
- private HashMap<String, Boolean> linkTargetIDs = null;
-
- private final int dockOffY, dockOffX;
-
- private final Float[] growXs, growYs;
-
- private final ArrayList<LayoutCallback> callbackList;
-
- /** Constructor.
- * @param container The container that will be laid out.
- * @param lc The form flow constraints.
- * @param rowConstr The rows specifications. If more cell rows are required, the last element will be used for when there is no corresponding element in this array.
- * @param colConstr The columns specifications. If more cell rows are required, the last element will be used for when there is no corresponding element in this array.
- * @param fcMap The map containing the parsed constraints for each child component of <code>parent</code>. Will not be alterted.
- * @param callbackList A list of callbacks or <code>null</code> if none. Will not be alterted.
- */
- public Grid(ContainerWrapper container, LC lc, AC rowConstr, AC colConstr, Map<ComponentWrapper, CC> fcMap, ArrayList<LayoutCallback> callbackList)
- {
- this.lc = lc;
- this.rowConstr = rowConstr;
- this.colConstr = colConstr;
- this.container = container;
- this.callbackList = callbackList;
-
- int wrap = lc.getWrapAfter() != 0 ? lc.getWrapAfter() : (lc.isFlowX() ? colConstr : rowConstr).getConstaints().length;
-
- final ComponentWrapper[] comps = container.getComponents();
-
- boolean hasTagged = false; // So we do not have to sort if it will not do any good
- boolean hasPushX = false, hasPushY = false;
- final int[] p = new int[2];
- final ArrayList<int[]> spannedRects = new ArrayList<int[]>(2);
-
- final DimConstraint[] specs = (lc.isFlowX() ? rowConstr : colConstr).getConstaints();
-
- int sizeGroupsX = 0, sizeGroupsY = 0;
- int[] dockInsets = null; // top, left, bottom, right insets for docks.
-
- LinkHandler.clearTemporaryBounds(container.getLayout());
-
- for (int i = 0; i < comps.length;) {
- ComponentWrapper comp = comps[i];
- CC rootCc = fcMap.get(comp);
-
- int hideMode = comp.isVisible() ? -1 : rootCc.getHideMode() != -1 ? rootCc.getHideMode() : lc.getHideMode();
-
- if (rootCc == null || hideMode == 3) { // To work with situations where there are components that does not have a layout manager, or not this one.
- if (rootCc != null)
- setLinkedBounds(comp, rootCc, comp.getX(), comp.getY(), comp.getWidth(), comp.getHeight(), rootCc.isExternal());
- i++;
- continue; // The "external" component should not be handled further.
- }
-
- if (rootCc.getHorizontal().getSizeGroup() != null)
- sizeGroupsX++;
- if (rootCc.getVertical().getSizeGroup() != null)
- sizeGroupsY++;
-
- // Special treatment of absolute positioned components.
- UnitValue[] pos = getPos(comp, rootCc);
- BoundSize[] cbSz = getCallbackSize(comp, rootCc);
- if (pos != null || rootCc.isExternal()) {
-
- // Check if link information should be saved later.
- if (pos != null) {
- for (int l = 0; l < pos.length; l++) {
- UnitValue u = pos[l];
- if (u != null && u.isLinkedDeep())
- addLinkTargetIDs(u);
- }
- }
-
- CompWrap cw = new CompWrap(comp, rootCc, hideMode, pos, cbSz);
- Cell cell = grid.get(null);
- if (cell == null) {
- grid.put(null, new Cell(cw));
- } else {
- cell.compWraps.add(cw);
- }
-
- if (rootCc.isBoundsInGrid() == false || rootCc.isExternal()) {
- setLinkedBounds(comp, rootCc, comp.getX(), comp.getY(), comp.getWidth(), comp.getHeight(), rootCc.isExternal());
- i++;
- continue;
- }
- }
-
- if (rootCc.getDockSide() != -1) {
- if (dockInsets == null)
- dockInsets = new int[] {-MAX_DOCK_GRID, -MAX_DOCK_GRID, MAX_DOCK_GRID, MAX_DOCK_GRID};
-
- addDockingCell(dockInsets, rootCc.getDockSide(), new CompWrap(comp, rootCc, hideMode, pos, cbSz));
- i++;
- continue;
- }
-
- Boolean cellFlowX = rootCc.getFlowX();
- Cell cell = null;
-
- if (rootCc.isNewline())
- wrap(p, rootCc.getNewlineGapSize(), true);
-
- increase(p, rootCc.getSkip()); // Probably 0 advance...
-
- boolean rowNoGrid = lc.isNoGrid() || ((DimConstraint) LayoutUtil.getIndexSafe(specs, lc.isFlowX() ? p[1] : p[0])).isNoGrid();
-
- // Move to a free y, x if no absolute grid specified
- int cx = rootCc.getCellX();
- int cy = rootCc.getCellY();
- if ((cx < 0 || cy < 0) && rowNoGrid == false) {
- while (isCellFree(p[1], p[0], spannedRects) == false) {
- if (Math.abs(increase(p, 1)) >= wrap)
- wrap(p, null, true);
- }
- } else {
- if (cx >= 0 && cy >= 0) {
- if (cy >= 0) {
- p[0] = cx;
- p[1] = cy;
- } else { // Only one coordinate is specified. Use the current row (flowx) or column (flowy) to fill in.
- if (lc.isFlowX()) {
- p[0] = cx;
- } else {
- p[1] = cx;
- }
- }
- }
- cell = getCell(p[1], p[0]); // Might be null
- }
-
- // If cell is not created yet, create it and set it.
- if (cell == null) {
- int spanx = Math.min(rowNoGrid && lc.isFlowX() ? LayoutUtil.INF : rootCc.getSpanX(), MAX_GRID - p[0]);
- int spany = Math.min(rowNoGrid && !lc.isFlowX() ? LayoutUtil.INF : rootCc.getSpanY(), MAX_GRID - p[1]);
-
- cell = new Cell(spanx, spany, cellFlowX != null ? cellFlowX.booleanValue() : lc.isFlowX());
-
- setCell(p[1], p[0], cell);
-
- // Add a rectangle so we can know that spanned cells occupy more space.
- if (spanx > 1 || spany > 1)
- spannedRects.add(new int[] {p[0], p[1], spanx, spany});
- }
-
- // Add the one, or all, components that split the grid position to the same Cell.
- boolean forceWrap = false;
- BoundSize wrapGap = null;
- int splitLeft = rowNoGrid ? LayoutUtil.INF : rootCc.getSplit() - 1;
- boolean splitExit = false;
- for (; splitLeft >= 0 && forceWrap == false && i < comps.length; splitLeft--) {
- ComponentWrapper compAdd = comps[i];
- CC cc = fcMap.get(compAdd); // Can not be null.
-
- hideMode = compAdd.isVisible() ? -1 : cc.getHideMode() != -1 ? cc.getHideMode() : lc.getHideMode();
-
- if (cc == null || cc.isExternal() || hideMode == 3) {
- i++;
- continue; // To work with situations where there are components that does not have a layout manager, or not this one.
- }
-
- hasPushX |= (cc.getPushX() != null);
- hasPushY |= (cc.getPushY() != null);
-
- if (cc != rootCc) { // If not first in a cell
- if (cc.isNewline() || cc.isBoundsInGrid() == false)
- break;
-
- if (splitLeft > 0 && cc.getSkip() > 0) {
- splitExit = true;
- break;
- }
-
- pos = getPos(compAdd, cc);
- cbSz = getCallbackSize(compAdd, cc);
- }
-
- CompWrap cw = new CompWrap(compAdd, cc, hideMode, pos, cbSz);
- cell.compWraps.add(cw);
- cell.hasTagged |= cc.getTag() != null;
- hasTagged |= cell.hasTagged;
-
- if (cc != rootCc) {
- if (cc.getHorizontal().getSizeGroup() != null)
- sizeGroupsX++;
- if (cc.getVertical().getSizeGroup() != null)
- sizeGroupsY++;
- }
-
- int flowSpan = lc.isFlowX() ? rootCc.getSpanX() : rootCc.getSpanY();
- forceWrap = (cc.isWrap() || (flowSpan == LayoutUtil.INF && splitLeft == 0));
- wrapGap = cc.getWrapGapSize();
- i++;
- }
-
- if (forceWrap) {
- wrap(p, wrapGap, true);
- } else if (rowNoGrid == false) {
- int span = lc.isFlowX() ? cell.spanx : cell.spany;
- if (Math.abs((lc.isFlowX() ? p[0] : p[1])) + span >= wrap) {
- wrap(p, null, true);
- } else {
- int adv = lc.isFlowX() ? cell.spanx : cell.spany;
- if (splitExit)
- adv--;
- increase(p, adv);
- }
- }
- }
-
- // If there were size groups, calculate the largest values in the groups (for min/pref/max) and enforce them on the rest in the group.
- if (sizeGroupsX > 0 || sizeGroupsY > 0) {
- HashMap<String, int[]> sizeGroupMapX = sizeGroupsX > 0 ? new HashMap<String, int[]>(sizeGroupsX) : null;
- HashMap<String, int[]> sizeGroupMapY = sizeGroupsY > 0 ? new HashMap<String, int[]>(sizeGroupsY) : null;
- ArrayList<CompWrap> sizeGroupCWs = new ArrayList<CompWrap>(Math.max(sizeGroupsX, sizeGroupsY));
-
- for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) {
- Cell cell = it.next();
- for (int i = 0; i < cell.compWraps.size(); i++) {
- CompWrap cw = cell.compWraps.get(i);
-
- if (cw.cc.getHorizontal().getSizeGroup() != null || cw.cc.getVertical().getSizeGroup() != null) {
- addToSizeGroup(sizeGroupMapX, cw.cc.getHorizontal().getSizeGroup(), cw.horSizes);
- addToSizeGroup(sizeGroupMapY, cw.cc.getVertical().getSizeGroup(), cw.verSizes);
- sizeGroupCWs.add(cw);
- }
- }
- }
-
- // Set/equalize the sizeGroups to same the values.
- if (sizeGroupCWs != null) {
- for (int i = 0; i < sizeGroupCWs.size(); i++) {
- CompWrap cw = sizeGroupCWs.get(i);
- if (sizeGroupMapX != null)
- cw.setSizes(sizeGroupMapX.get(cw.cc.getHorizontal().getSizeGroup()), true); // Target method handles null sizes
- if (sizeGroupMapY != null)
- cw.setSizes(sizeGroupMapY.get(cw.cc.getVertical().getSizeGroup()), false); // Target method handles null sizes
- }
- }
- }
-
- if (hasTagged)
- sortCellsByPlatform(grid.values(), container);
-
- // Calculate gaps now that the cells are filled and we know all adjacent components.
- boolean ltr = LayoutUtil.isLeftToRight(lc, container);
- for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) {
- Cell cell = it.next();
- ArrayList<CompWrap> cws = cell.compWraps;
-
- for (int i = 0, lastI = cws.size() - 1; i <= lastI; i++) {
- CompWrap cw = cws.get(i);
- ComponentWrapper cwBef = i > 0 ? cws.get(i - 1).comp : null;
- ComponentWrapper cwAft = i < lastI ? cws.get(i + 1).comp : null;
-
- String tag = fcMap.get(cw.comp).getTag();
- CC ccBef = cwBef != null ? fcMap.get(cwBef) : null;
- CC ccAft = cwAft != null ? fcMap.get(cwAft) : null;
-
- cw.calcGaps(cwBef, ccBef, cwAft, ccAft, tag, cell.flowx, ltr);
- }
- }
-
- dockOffX = getDockInsets(colIndexes);
- dockOffY = getDockInsets(rowIndexes);
-
- // Add synthetic indexes for empty rows and columns so they can get a size
- for (int i = 0, iSz = rowConstr.getCount(); i < iSz; i++)
- rowIndexes.add(new Integer(i));
- for (int i = 0, iSz = colConstr.getCount(); i < iSz; i++)
- colIndexes.add(new Integer(i));
-
- colGroupLists = divideIntoLinkedGroups(false);
- rowGroupLists = divideIntoLinkedGroups(true);
-
- growXs = getDefaultGrowWeights(hasPushX, false);
- growYs = getDefaultGrowWeights(hasPushY, true);
-
- }
-
- /** If the container (parent) that this grid is laying out has changed its bounds, call this method to
- * clear any cached values.
- */
- public void invalidateContainerSize()
- {
- colFlowSpecs = null;
- }
-
- /** Does the actual layout. Uses many values calculated in the constructor.
- * @param bounds The bounds to layout against. Normally that of the parent. [x, y, width, height].
- * @param alignX The alignment for the x-axis.
- * @param alignY The alignment for the y-axis.
- * @param debug If debug information should be saved in {@link #debugRects}.
- * @param checkPrefChange If a check should be done to see if the setting of any new bounds changes the preferred size
- * of a component. This is normally only turned on for SWT as SWT has a notion of width vs height calculation.
- * @return If the layout has probably change the preferred size and there is need for a new layout (normally only SWT).
- */
- public boolean layout(int[] bounds, UnitValue alignX, UnitValue alignY, boolean debug, boolean checkPrefChange)
- {
- if (debug)
- debugRects = new ArrayList<int[]>();
-
- checkSizeCalcs();
-
- resetLinkValues(true);
-
- layoutInOneDim(bounds[2], alignX, false, growXs);
- layoutInOneDim(bounds[3], alignY, true, growYs);
-
- HashMap<String, Integer> endGrpXMap = null, endGrpYMap = null;
- int compCount = container.getComponentCount();
-
- // Transfer the calculated bound from the ComponentWrappers to the actual Components.
- boolean layoutAgain = false;
- if (compCount > 0) {
- for (int j = 0; j < (linkTargetIDs != null ? 2 : 1); j++) { // First do the calculations (maybe more than once) then set the bounds when done
- boolean doAgain;
- int count = 0;
- do {
- doAgain = false;
- for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) {
- ArrayList<CompWrap> compWraps = it.next().compWraps;
- for (int i = 0, iSz = compWraps.size(); i < iSz; i++) {
- CompWrap cw = compWraps.get(i);
-
- if (j == 0) {
- doAgain |= doAbsoluteCorrections(cw, bounds);
- if (doAgain == false) { // If we are going to do this again, do not bother this time around
- if (cw.cc.getHorizontal().getEndGroup() != null)
- endGrpXMap = addToEndGroup(endGrpXMap, cw.cc.getHorizontal().getEndGroup(), cw.x + cw.w);
- if (cw.cc.getVertical().getEndGroup() != null)
- endGrpYMap = addToEndGroup(endGrpYMap, cw.cc.getVertical().getEndGroup(), cw.y + cw.h);
- }
- }
-
- if (linkTargetIDs == null || j == 1) {
- if (cw.cc.getHorizontal().getEndGroup() != null)
- cw.w = endGrpXMap.get(cw.cc.getHorizontal().getEndGroup()).intValue() - cw.x;
- if (cw.cc.getVertical().getEndGroup() != null)
- cw.h = endGrpYMap.get(cw.cc.getVertical().getEndGroup()).intValue() - cw.y;
-
- cw.x += bounds[0];
- cw.y += bounds[1];
- layoutAgain = cw.transferBounds(checkPrefChange && !layoutAgain);
-
- if (callbackList != null) {
- for (int cb = 0; cb < callbackList.size(); cb++)
- callbackList.get(cb).correctBounds(cw.comp);
- }
- }
- }
- }
- clearGroupLinkBounds();
- if (++count > ((compCount << 3) + 10)) {
- System.err.println("Unstable Cyclic Dependency in absolute-linked values!");
- break;
- }
-
- } while (doAgain);
- }
- }
-
- // Add debug shapes for the "cells". Use the CompWraps as base for inding the cells.
- if (debug) {
- Collection<Cell> cwColl = grid.values();
- for (Iterator<Cell> it = cwColl.iterator(); it.hasNext();) {
- ArrayList<CompWrap> compWraps = it.next().compWraps;
- for (int i = 0, iSz = compWraps.size(); i < iSz; i++) {
- CompWrap cw = compWraps.get(i);
- LinkedDimGroup hGrp = getGroupContaining(colGroupLists, cw);
- LinkedDimGroup vGrp = getGroupContaining(rowGroupLists, cw);
-
- if (hGrp != null && vGrp != null)
- debugRects.add(new int[] {hGrp.lStart + bounds[0] - (hGrp.fromEnd ? hGrp.lSize : 0), vGrp.lStart + bounds[1] - (vGrp.fromEnd ? vGrp.lSize : 0), hGrp.lSize, vGrp.lSize});
- }
- }
- }
- return layoutAgain;
- }
-
- public void paintDebug()
- {
- if (debugRects != null) {
- container.paintDebugOutline();
-
- ArrayList<int[]> painted = new ArrayList<int[]>();
- for (int i = 0, iSz = debugRects.size(); i < iSz; i++) {
- int[] r = debugRects.get(i);
- if (painted.contains(r) == false) {
- container.paintDebugCell(r[0], r[1], r[2], r[3]);
- painted.add(r);
- }
- }
-
- for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) {
- ArrayList<CompWrap> compWraps = it.next().compWraps;
- for (int i = 0, iSz = compWraps.size(); i < iSz; i++)
- compWraps.get(i).comp.paintDebugOutline();
- }
- }
- }
-
- public final int[] getWidth()
- {
- checkSizeCalcs();
- return width;
- }
-
- public final int[] getHeight()
- {
- checkSizeCalcs();
- return height;
- }
-
- private void checkSizeCalcs()
- {
- if (colFlowSpecs == null) {
- colFlowSpecs = calcRowsOrColsSizes(colGroupLists, growXs, container.getWidth(), true);
- rowFlowSpecs = calcRowsOrColsSizes(rowGroupLists, growYs, container.getHeight(), false);
-
- width = getMinPrefMaxSumSize(colFlowSpecs.sizes);
- height = getMinPrefMaxSumSize(rowFlowSpecs.sizes);
-
- resetLinkValues(false);
-
- adjustSizeForAbsolute(width, true);
- adjustSizeForAbsolute(height, false);
- }
- }
-
- private final UnitValue[] getPos(ComponentWrapper cw, CC cc)
- {
- UnitValue[] cbPos = null;
- if (callbackList != null) {
- for (int i = 0; i < callbackList.size() && cbPos == null; i++)
- cbPos = callbackList.get(i).getPosition(cw); // NOT a copy!
- }
-
- // If one is null, return the other (which many also be null)
- UnitValue[] ccPos = cc.getPos(); // A copy!!
- if (cbPos == null || ccPos == null)
- return cbPos != null ? cbPos : ccPos;
-
- // Merge
- for (int i = 0; i < 4; i++) {
- UnitValue cbUv = cbPos[i];
- if (cbUv != null)
- ccPos[i] = cbUv;
- }
-
- return ccPos;
- }
- private final BoundSize[] getCallbackSize(ComponentWrapper cw, CC cc)
- {
- if (callbackList != null) {
- for (int i = 0; i < callbackList.size(); i++) {
- BoundSize[] bs = callbackList.get(i).getSize(cw); // NOT a copy!
- if (bs != null)
- return bs;
- }
- }
- return null;
- }
-
- private final int getDockInsets(TreeSet<Integer> set)
- {
- int c = 0;
- for (Iterator<Integer> it = set.iterator(); it.hasNext();) {
- if (it.next().intValue() < -MAX_GRID) {
- c++;
- } else {
- break; // Since they are sorted we can break
- }
- }
- return c;
- }
-
- /**
- * @param cw Never <code>null</code>.
- * @param fc Never <code>null</code>.
- * @param external The bounds should be stored even if they are not in {@link #linkTargetIDs}.
- * @return IF a change has been done.
- */
- private boolean setLinkedBounds(ComponentWrapper cw, CC fc, int x, int y, int w, int h, boolean external)
- {
- String id = fc.getId() != null ? fc.getId() : cw.getLinkId();
- if (id == null)
- return false;
-
- String gid = null;
- int grIx = id.indexOf('.');
- if (grIx != -1 ) {
- gid = id.substring(0, grIx);
- id = id.substring(grIx + 1);
- }
-
- Object lay = container.getLayout();
- boolean changed = false;
- if (external || (linkTargetIDs != null && linkTargetIDs.containsKey(id)))
- changed = LinkHandler.setBounds(lay, id, x, y, w, h, !external, false);
-
- if (gid != null && (external || (linkTargetIDs != null && linkTargetIDs.containsKey(gid)))) {
- if (linkTargetIDs == null)
- linkTargetIDs = new HashMap<String, Boolean>(4);
-
- linkTargetIDs.put(gid, Boolean.TRUE);
- changed |= LinkHandler.setBounds(lay, gid, x, y, w, h, !external, true);
- }
-
- return changed;
- }
-
- private void addLinkTargetIDs(UnitValue uv)
- {
- if (uv.isLinked()) {
- if (linkTargetIDs == null)
- linkTargetIDs = new HashMap<String, Boolean>(4);
-
- linkTargetIDs.put(uv.getLinkTargetId(), null);
- } else {
- for (int i = uv.getSubUnitCount() - 1; i >= 0; i--) {
- UnitValue subUv = uv.getSubUnitValue(i);
- if (subUv.isLinkedDeep())
- addLinkTargetIDs(subUv);
- }
- }
- }
-
- /** Go to next cell.
- * @param p The point to increase
- * @param cnt How many cells to advance.
- * @return The new value in the "incresing" dimension.
- */
- private final int increase(int[] p, int cnt)
- {
- return lc.isFlowX() ? (p[0] += cnt) : (p[1] += cnt);
- }
-
- /** Wraps to the next row or column depending on if horizontal flow or vertical flow is used.
- * @param p The point to wrap and thus set either x or y to 0 and increase the other one.
- * @param gapSize The gaps size specified in a "wrap XXX" or "newline XXX" or <code>null</code> if none.
- * @param isWrap If gapSize is from a "wrap" (true) or "newline" (false).
- */
- private final void wrap(int[] p, BoundSize gapSize, boolean isWrap)
- {
- boolean flowx = lc.isFlowX();
- p[0] = flowx ? 0 : p[0] + 1;
- p[1] = flowx ? p[1] + 1 : 0;
-
- if (gapSize != null) {
- if (wrapGapMap == null)
- wrapGapMap = new HashMap<Integer, BoundSize>(8);
- int ix = p[flowx ? 1 : 0];
- if (isWrap == false)
- ix--; // newline. Use index before increment.
- wrapGapMap.put(new Integer(ix), gapSize);
-
- // add the row/column so that the gap in the last row/col will not be removed.
- if (flowx) {
- rowIndexes.add(new Integer(p[1]));
- } else {
- colIndexes.add(new Integer(p[0]));
- }
- }
- }
-
- /** Sort components (normally buttons in a button bar) so they appear in the correct order.
- * @param cells The cells to sort.
- * @param parent The parent.
- */
- private static void sortCellsByPlatform(Collection<Cell> cells, ContainerWrapper parent)
- {
- String order = PlatformDefaults.getButtonOrder();
- String orderLo = order.toLowerCase();
-
- int unrelSize = PlatformDefaults.convertToPixels(1, "u", true, 0, parent, null);
-
- if (unrelSize == UnitConverter.UNABLE)
- throw new IllegalArgumentException("'unrelated' not recognized by PlatformDefaults!");
-
- int[] gapUnrel = new int[] {unrelSize, unrelSize, LayoutUtil.NOT_SET};
- int[] flGap = new int[] {0, 0, LayoutUtil.NOT_SET};
-
- for (Iterator<Cell> it = cells.iterator(); it.hasNext();) {
- Cell cell = it.next();
- if (cell.hasTagged == false)
- continue;
-
- CompWrap prevCW = null;
- boolean nextUnrel = false;
- boolean nextPush = false;
- ArrayList<CompWrap> sortedList = new ArrayList<CompWrap>(cell.compWraps.size());
-
- for (int i = 0, iSz = orderLo.length(); i < iSz; i++) {
- char c = orderLo.charAt(i);
- if (c == '+' || c == '_') {
- nextUnrel = true;
- if (c == '+')
- nextPush = true;
- } else {
- String tag = PlatformDefaults.getTagForChar(c);
- if (tag != null) {
- for (int j = 0, jSz = cell.compWraps.size(); j < jSz; j++) {
- CompWrap cw = cell.compWraps.get(j);
- if (tag.equals(cw.cc.getTag())) {
- if (Character.isUpperCase(order.charAt(i))) {
- int min = PlatformDefaults.getMinimumButtonWidth().getPixels(0, parent, cw.comp);
- if (min > cw.horSizes[LayoutUtil.MIN])
- cw.horSizes[LayoutUtil.MIN] = min;
-
- correctMinMax(cw.horSizes);
- }
-
- sortedList.add(cw);
-
- if (nextUnrel) {
- (prevCW != null ? prevCW : cw).mergeGapSizes(gapUnrel, cell.flowx, prevCW == null);
- if (nextPush) {
- cw.forcedPushGaps = 1;
- nextUnrel = false;
- nextPush = false;
- }
- }
-
- // "unknown" components will always get an Unrelated gap.
- if (c == 'u')
- nextUnrel = true;
- prevCW = cw;
- }
- }
- }
- }
- }
-
- // If we have a gap that was supposed to push but no more components was found to but the "gap before" then compensate.
- if (sortedList.size() > 0) {
- CompWrap cw = sortedList.get(sortedList.size() - 1);
- if (nextUnrel) {
- cw.mergeGapSizes(gapUnrel, cell.flowx, false);
- if (nextPush)
- cw.forcedPushGaps |= 2;
- }
-
- // Remove first and last gap if not set explicitly.
- if (cw.cc.getHorizontal().getGapAfter() == null)
- cw.setGaps(flGap, 3);
-
- cw = sortedList.get(0);
- if (cw.cc.getHorizontal().getGapBefore() == null)
- cw.setGaps(flGap, 1);
- }
-
- // Exchange the unsorted CompWraps for the sorted one.
- if (cell.compWraps.size() == sortedList.size()) {
- cell.compWraps.clear();
- } else {
- cell.compWraps.removeAll(sortedList);
- }
- cell.compWraps.addAll(sortedList);
- }
- }
-
- private Float[] getDefaultGrowWeights(boolean hasPush, boolean isRows)
- {
- if (hasPush == false && (isRows ? lc.isFillY() : lc.isFillX()) == false)
- return null;
-
- ArrayList<LinkedDimGroup>[] groupLists = isRows ? rowGroupLists : colGroupLists;
-
- Float[] gwArr = GROW_100; // Only create specific if any of the components have grow.
- for (int i = 0, ix = 1; i < groupLists.length; i++, ix += 2) {
- ArrayList<LinkedDimGroup> grps = groupLists[i];
- Float rowGw = null;
- for (int j = 0; j < grps.size(); j++) {
- LinkedDimGroup grp = grps.get(j);
-
- for (int c = 0; c < grp._compWraps.size(); c++) {
- CompWrap cw = grp._compWraps.get(c);
- Float gw = hasPush ? (isRows ? cw.cc.getPushY() : cw.cc.getPushX()) : (isRows ? cw.cc.getVertical() : cw.cc.getHorizontal()).getGrow();
- if (rowGw == null || (gw != null && gw.floatValue() > rowGw.floatValue()))
- rowGw = gw;
- }
- }
-
- if (rowGw != null) {
- if (gwArr == GROW_100)
- gwArr = new Float[(groupLists.length << 1) + 1];
- gwArr[ix] = rowGw;
- }
- }
-
- return gwArr;
- }
-
- private void clearGroupLinkBounds()
- {
- if (linkTargetIDs == null)
- return;
-
- for (Iterator<Map.Entry<String,Boolean>> it = linkTargetIDs.entrySet().iterator(); it.hasNext();) {
- Map.Entry<String, Boolean> o = it.next();
- if (o.getValue() == Boolean.TRUE)
- LinkHandler.clearBounds(container.getLayout(), o.getKey());
- }
- }
-
- private void resetLinkValues(boolean parentSize)
- {
- Object lay = container.getLayout();
- LinkHandler.clearTemporaryBounds(lay);
-
- boolean defIns = !hasDocks();
-
- int parW = parentSize ? container.getWidth() : 0;
- int parH = parentSize ? container.getHeight() : 0;
- int insX = LayoutUtil.getInsets(lc, 0, defIns).getPixels(0, container, null);
- int insY = LayoutUtil.getInsets(lc, 1, defIns).getPixels(0, container, null);
- int insW = parW - insX - LayoutUtil.getInsets(lc, 2, defIns).getPixels(0, container, null);
- int insH = parH - insY - LayoutUtil.getInsets(lc, 3, defIns).getPixels(0, container, null);
-
- LinkHandler.setBounds(lay, "visual", insX, insY, insW, insH, true, false);
- LinkHandler.setBounds(lay, "container", 0, 0, parW, parH, true, false);
- }
-
- /** Returns the {@link net.miginfocom.layout.Grid.LinkedDimGroup} that has the {@link net.miginfocom.layout.Grid.CompWrap}
- * <code>cw</code>.
- * @param groupLists The lists to search in.
- * @param cw The component wrap to find.
- * @return The linked group or <code>null</code> if none had the component wrap.
- */
- private static LinkedDimGroup getGroupContaining(ArrayList<LinkedDimGroup>[] groupLists, CompWrap cw)
- {
- for (int i = 0; i < groupLists.length; i++) {
- ArrayList<LinkedDimGroup> groups = groupLists[i];
- for (int j = 0, jSz = groups.size(); j < jSz; j++) {
- ArrayList<CompWrap> cwList = groups.get(j)._compWraps;
- for (int k = 0, kSz = cwList.size(); k < kSz; k++) {
- if (cwList.get(k) == cw)
- return groups.get(j);
- }
- }
- }
- return null;
- }
-
- private boolean doAbsoluteCorrections(CompWrap cw, int[] bounds)
- {
- boolean changed = false;
-
- int[] stSz = getAbsoluteDimBounds(cw, bounds[2], true);
- if (stSz != null)
- cw.setDimBounds(stSz[0], stSz[1], true);
-
- stSz = getAbsoluteDimBounds(cw, bounds[3], false);
- if (stSz != null)
- cw.setDimBounds(stSz[0], stSz[1], false);
-
- // If there is a link id, store the new bounds.
- if (linkTargetIDs != null)
- changed = setLinkedBounds(cw.comp, cw.cc, cw.x, cw.y, cw.w, cw.h, false);
-
- return changed;
- }
-
- private void adjustSizeForAbsolute(int[] curSizes, boolean isHor)
- {
- Cell absCell = grid.get(null);
- if (absCell == null || absCell.compWraps.size() == 0)
- return;
-
- ArrayList<CompWrap> cws = absCell.compWraps;
-
- int maxEnd = 0;
- for (int j = 0, cwSz = absCell.compWraps.size(); j < cwSz + 3; j++) { // "Do Again" max absCell.compWraps.size() + 3 times.
- boolean doAgain = false;
- for (int i = 0; i < cwSz; i++) {
- CompWrap cw = cws.get(i);
- int[] stSz = getAbsoluteDimBounds(cw, 0, isHor);
- int end = stSz[0] + stSz[1];
- if (maxEnd < end)
- maxEnd = end;
-
- // If there is a link id, store the new bounds.
- if (linkTargetIDs != null)
- doAgain |= setLinkedBounds(cw.comp, cw.cc, stSz[0], stSz[0], stSz[1], stSz[1], false);
- }
- if (doAgain == false)
- break;
-
- // We need to check this again since the coords may be smaller this round.
- maxEnd = 0;
- clearGroupLinkBounds();
- }
-
- maxEnd += LayoutUtil.getInsets(lc, isHor ? 3 : 2, !hasDocks()).getPixels(0, container, null);
-
- if (curSizes[LayoutUtil.MIN] < maxEnd)
- curSizes[LayoutUtil.MIN] = maxEnd;
- if (curSizes[LayoutUtil.PREF] < maxEnd)
- curSizes[LayoutUtil.PREF] = maxEnd;
- }
-
- private int[] getAbsoluteDimBounds(CompWrap cw, int refSize, boolean isHor)
- {
- if (cw.cc.isExternal()) {
- if (isHor) {
- return new int[] {cw.comp.getX(), cw.comp.getWidth()};
- } else {
- return new int[] {cw.comp.getY(), cw.comp.getHeight()};
- }
- }
-
- int[] plafPad = lc.isVisualPadding() ? cw.comp.getVisualPadding() : null;
- UnitValue[] pad = cw.cc.getPadding();
-
- // If no changes do not create a lot of objects
- if (cw.pos == null && plafPad == null && pad == null)
- return null;
-
- // Set start
- int st = isHor ? cw.x : cw.y;
- int sz = isHor ? cw.w : cw.h;
-
- // If absolute, use those coordinates instead.
- if (cw.pos != null) {
- UnitValue stUV = cw.pos != null ? cw.pos[isHor ? 0 : 1] : null;
- UnitValue endUV = cw.pos != null ? cw.pos[isHor ? 2 : 3] : null;
-
- int minSz = cw.getSize(LayoutUtil.MIN, isHor);
- int maxSz = cw.getSize(LayoutUtil.MAX, isHor);
- sz = Math.min(Math.max(cw.getSize(LayoutUtil.PREF, isHor), minSz), maxSz);
-
- if (stUV != null) {
- st = stUV.getPixels(stUV.getUnit() == UnitValue.ALIGN ? sz : refSize, container, cw.comp);
-
- if (endUV != null) // if (endUV == null && cw.cc.isBoundsIsGrid() == true)
- sz = Math.min(Math.max((isHor ? (cw.x + cw.w) : (cw.y + cw.h)) - st, minSz), maxSz);
- }
-
- if (endUV != null) {
- if (stUV != null) { // if (stUV != null || cw.cc.isBoundsIsGrid()) {
- sz = Math.min(Math.max(endUV.getPixels(refSize, container, cw.comp) - st, minSz), maxSz);
- } else {
- st = endUV.getPixels(refSize, container, cw.comp) - sz;
- }
- }
- }
-
- // If constraint has padding -> correct the start/size
- if (pad != null) {
- UnitValue uv = pad[isHor ? 1 : 0];
- int p = uv != null ? uv.getPixels(refSize, container, cw.comp) : 0;
- st += p;
- uv = pad[isHor ? 3 : 2];
- sz += -p + (uv != null ? uv.getPixels(refSize, container, cw.comp) : 0);
- }
-
- // If the plaf converter has padding -> correct the start/size
- if (plafPad != null) {
- int p = plafPad[isHor ? 1 : 0];
- st += p;
- sz += -p + (plafPad[isHor ? 3 : 2]);
- }
-
- return new int[] {st, sz};
- }
-
- private void layoutInOneDim(int refSize, UnitValue align, boolean isRows, Float[] defaultGrowW)
- {
- boolean fromEnd = !(isRows ? lc.isTopToBottom() : LayoutUtil.isLeftToRight(lc, container));
- DimConstraint[] primDCs = (isRows ? rowConstr : colConstr).getConstaints();
- FlowSizeSpec fss = isRows ? rowFlowSpecs : colFlowSpecs;
- ArrayList<LinkedDimGroup>[] rowCols = isRows ? rowGroupLists : colGroupLists;
-
- int[] rowColSizes = LayoutUtil.calculateSerial(fss.sizes, fss.resConstsInclGaps, defaultGrowW, LayoutUtil.PREF, refSize);
-
- if (LayoutUtil.isDesignTime(container)) {
- TreeSet<Integer> indexes = isRows ? rowIndexes : colIndexes;
- int[] ixArr = new int[indexes.size()];
- int ix = 0;
- for (Integer i : indexes)
- ixArr[ix++] = i.intValue();
-
- putSizesAndIndexes(container.getComponent(), rowColSizes, ixArr, isRows);
- }
-
- int curPos = align != null ? Math.round(align.getPixels(refSize - LayoutUtil.sum(rowColSizes), container, null)) : 0;
-
- if (fromEnd)
- curPos = refSize - curPos;
-
- for (int i = 0 ; i < rowCols.length; i++) {
- ArrayList<LinkedDimGroup> linkedGroups = rowCols[i];
- int scIx = i - (isRows ? dockOffY : dockOffX);
-
- int bIx = i << 1;
- int bIx2 = bIx + 1;
-
- curPos += (fromEnd ? -rowColSizes[bIx] : rowColSizes[bIx]);
-
- DimConstraint primDC = scIx >= 0 ? primDCs[scIx >= primDCs.length ? primDCs.length - 1 : scIx] : DOCK_DIM_CONSTRAINT;
-
- int rowSize = rowColSizes[bIx2];
-
- for (int j = 0; j < linkedGroups.size(); j++) {
- LinkedDimGroup group = linkedGroups.get(j);
- int groupSize = rowSize;
- if (group.span > 1)
- groupSize = LayoutUtil.sum(rowColSizes, bIx2, Math.min((group.span << 1) - 1, rowColSizes.length - bIx2 - 1));
-
- group.layout(primDC, curPos, groupSize, group.span);
- }
-
- curPos += (fromEnd ? -rowSize : rowSize);
- }
- }
-
- private void addToSizeGroup(HashMap<String, int[]> sizeGroups, String sizeGroup, int[] size)
- {
- if (sizeGroups == null)
- return;
-
- int[] sgSize = sizeGroups.get(sizeGroup);
- if (sgSize == null) {
- sizeGroups.put(sizeGroup, new int[] {size[LayoutUtil.MIN], size[LayoutUtil.PREF], size[LayoutUtil.MAX]});
- } else {
- sgSize[LayoutUtil.MIN] = Math.max(size[LayoutUtil.MIN], sgSize[LayoutUtil.MIN]);
- sgSize[LayoutUtil.PREF] = Math.max(size[LayoutUtil.PREF], sgSize[LayoutUtil.PREF]);
- sgSize[LayoutUtil.MAX] = Math.min(size[LayoutUtil.MAX], sgSize[LayoutUtil.MAX]);
- }
- }
-
- private HashMap<String, Integer> addToEndGroup(HashMap<String, Integer> endGroups, String endGroup, int end)
- {
- if (endGroup != null) {
- if (endGroups == null)
- endGroups = new HashMap<String, Integer>(2);
-
- Integer oldEnd = endGroups.get(endGroup);
- if (oldEnd == null || end > oldEnd.intValue())
- endGroups.put(endGroup, new Integer(end));
- }
- return endGroups;
- }
-
- /** Calculates Min, Preferred and Max size for the columns OR rows.
- * @param defGrow The default grow weight if the specs does not have anyone that will grow. Comes from "push" in the CC.
- * @return The sizes in a {@link net.miginfocom.layout.Grid.FlowSizeSpec}.
- */
- private FlowSizeSpec calcRowsOrColsSizes(ArrayList<LinkedDimGroup>[] groupsLists, Float[] defGrow, int refSize, boolean isHor)
- {
- DimConstraint[] primDCs = (isHor? colConstr : rowConstr).getConstaints();
- TreeSet<Integer> primIdexes = isHor ? colIndexes : rowIndexes;
-
- int[][] rowColBoundSizes = new int[primIdexes.size()][];
- HashMap<String, int[]> sizeGroupMap = new HashMap<String, int[]>(2);
- DimConstraint[] allDCs = new DimConstraint[primIdexes.size()];
-
- Iterator<Integer> primIt = primIdexes.iterator();
- for (int r = 0; r < rowColBoundSizes.length; r++) {
- int cellIx = primIt.next().intValue();
- int[] rowColSizes = new int[3];
-
- if (cellIx >= -MAX_GRID && cellIx <= MAX_GRID) { // If not dock cell
- allDCs[r] = primDCs[cellIx >= primDCs.length ? primDCs.length - 1 : cellIx];
- } else {
- allDCs[r] = DOCK_DIM_CONSTRAINT;
- }
-
- ArrayList<LinkedDimGroup> groups = groupsLists[r];
-
- int[] groupSizes = new int[] {
- getTotalGroupsSizeParallel(groups, LayoutUtil.MIN, false),
- getTotalGroupsSizeParallel(groups, LayoutUtil.PREF, false),
- LayoutUtil.INF};
-
- correctMinMax(groupSizes);
- BoundSize dimSize = allDCs[r].getSize();
-
- for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.MAX; sType++) {
-
- int rowColSize = groupSizes[sType];
-
- UnitValue uv = dimSize != null ? dimSize.getSize(sType) : null;
- if (uv != null) {
- // If the size of the column is a link to some other size, use that instead
- int unit = uv.getUnit();
- if (unit == UnitValue.PREF_SIZE) {
- rowColSize = groupSizes[LayoutUtil.PREF];
- } else if (unit == UnitValue.MIN_SIZE) {
- rowColSize = groupSizes[LayoutUtil.MIN];
- } else if (unit == UnitValue.MAX_SIZE) {
- rowColSize = groupSizes[LayoutUtil.MAX];
- } else {
- rowColSize = uv.getPixels(refSize, container, null);
- }
- } else if (cellIx >= -MAX_GRID && cellIx <= MAX_GRID && rowColSize == 0) {
- rowColSize = LayoutUtil.isDesignTime(container) ? LayoutUtil.getDesignTimeEmptySize() : 0; // Empty rows with no size set gets XX pixels if design time
- }
-
- rowColSizes[sType] = rowColSize;
- }
-
- correctMinMax(rowColSizes);
- addToSizeGroup(sizeGroupMap, allDCs[r].getSizeGroup(), rowColSizes);
-
- rowColBoundSizes[r] = rowColSizes;
- }
-
- // Set/equalize the size groups to same the values.
- if (sizeGroupMap.size() > 0) {
- for (int r = 0; r < rowColBoundSizes.length; r++) {
- if (allDCs[r].getSizeGroup() != null)
- rowColBoundSizes[r] = sizeGroupMap.get(allDCs[r].getSizeGroup());
- }
- }
-
- // Add the gaps
- ResizeConstraint[] resConstrs = getRowResizeConstraints(allDCs);
-
- boolean[] fillInPushGaps = new boolean[allDCs.length + 1];
- int[][] gapSizes = getRowGaps(allDCs, refSize, isHor, fillInPushGaps);
-
-
- FlowSizeSpec fss = mergeSizesGapsAndResConstrs(resConstrs, fillInPushGaps, rowColBoundSizes, gapSizes, refSize, container);
-
- // Spanning components are not handled yet. Check and adjust the multi-row min/pref they enforce.
- adjustMinPrefForSpanningComps(allDCs, defGrow, fss, groupsLists);
-
- return fss;
- }
-
- private static int[] getMinPrefMaxSumSize(int[][] sizes)
- {
- int[] retSizes = new int[3];
-
- for (int i = 0; i < sizes.length; i++) {
- if (sizes[i] != null) {
- int[] size = sizes[i];
- for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.MAX; sType++) {
- int s = size[sType];
-
- if (s != LayoutUtil.NOT_SET) {
- if (sType == LayoutUtil.PREF) {
- int bnd = size[LayoutUtil.MAX];
- if (bnd != LayoutUtil.NOT_SET && bnd < s)
- s = bnd;
-
- bnd = size[LayoutUtil.MIN];
- if (bnd > s) // Includes s == LayoutUtil.NOT_SET since < 0.
- s = bnd;
- }
-
- retSizes[sType] += s; // MAX compensated below.
- }
- }
-
- // So that MAX is always correct.
- if (size[LayoutUtil.MAX] == LayoutUtil.NOT_SET)
- retSizes[LayoutUtil.MAX] = LayoutUtil.INF;
- }
- }
-
- return retSizes;
- }
-
- private static ResizeConstraint[] getRowResizeConstraints(DimConstraint[] specs)
- {
- ResizeConstraint[] resConsts = new ResizeConstraint[specs.length];
- for (int i = 0; i < resConsts.length; i++)
- resConsts[i] = specs[i].resize;
- return resConsts;
- }
-
- private static ResizeConstraint[] getComponentResizeConstraints(ArrayList<CompWrap> compWraps, boolean isHor)
- {
- ResizeConstraint[] resConsts = new ResizeConstraint[compWraps.size()];
- for (int i = 0; i < resConsts.length; i++) {
- CC fc = compWraps.get(i).cc;
- resConsts[i] = fc.getDimConstraint(isHor).resize;
-
- // Always grow docking components in the correct dimension.
- int dock = fc.getDockSide();
- if (isHor ? (dock == 0 || dock == 2) : (dock == 1 || dock == 3)) {
- ResizeConstraint dc = resConsts[i];
- resConsts[i] = new ResizeConstraint(dc.shrinkPrio, dc.shrink, dc.growPrio, ResizeConstraint.WEIGHT_100);
- }
- }
- return resConsts;
- }
-
- private static boolean[] getComponentGapPush(ArrayList<CompWrap> compWraps, boolean isHor)
- {
- // Make one element bigger and or the after gap with the next before gap.
- boolean[] barr = new boolean[compWraps.size() + 1];
- for (int i = 0; i < barr.length; i++) {
-
- boolean push = i > 0 ? compWraps.get(i - 1).isPushGap(isHor, false) : false;
-
- if (push == false && i < (barr.length - 1))
- push = compWraps.get(i).isPushGap(isHor, true);
-
- barr[i] = push;
- }
- return barr;
- }
-
- /** Returns the row gaps in pixel sizes. One more than there are <code>specs</code> sent in.
- * @param specs
- * @param refSize
- * @param isHor
- * @param fillInPushGaps If the gaps are pushing. <b>NOTE!</b> this argument will be filled in and thus changed!
- * @return The row gaps in pixel sizes. One more than there are <code>specs</code> sent in.
- */
- private int[][] getRowGaps(DimConstraint[] specs, int refSize, boolean isHor, boolean[] fillInPushGaps)
- {
- BoundSize defGap = isHor ? lc.getGridGapX() : lc.getGridGapY();
- if (defGap == null)
- defGap = isHor ? PlatformDefaults.getGridGapX() : PlatformDefaults.getGridGapY();
- int[] defGapArr = defGap.getPixelSizes(refSize, container, null);
-
- boolean defIns = !hasDocks();
-
- UnitValue firstGap = LayoutUtil.getInsets(lc, isHor ? 1 : 0, defIns);
- UnitValue lastGap = LayoutUtil.getInsets(lc, isHor ? 3 : 2, defIns);
-
- int[][] retValues = new int[specs.length + 1][];
-
- for (int i = 0, wgIx = 0; i < retValues.length; i++) {
- DimConstraint specBefore = i > 0 ? specs[i - 1] : null;
- DimConstraint specAfter = i < specs.length ? specs[i] : null;
-
- // No gap if between docking components.
- boolean edgeBefore = (specBefore == DOCK_DIM_CONSTRAINT || specBefore == null);
- boolean edgeAfter = (specAfter == DOCK_DIM_CONSTRAINT || specAfter == null);
- if (edgeBefore && edgeAfter)
- continue;
-
- BoundSize wrapGapSize = (wrapGapMap == null || isHor == lc.isFlowX() ? null : wrapGapMap.get(new Integer(wgIx++)));
-
- if (wrapGapSize == null) {
-
- int[] gapBefore = specBefore != null ? specBefore.getRowGaps(container, null, refSize, false) : null;
- int[] gapAfter = specAfter != null ? specAfter.getRowGaps(container, null, refSize, true) : null;
-
- if (edgeBefore && gapAfter == null && firstGap != null) {
-
- int bef = firstGap.getPixels(refSize, container, null);
- retValues[i] = new int[] {bef, bef, bef};
-
- } else if (edgeAfter && gapBefore == null && firstGap != null) {
-
- int aft = lastGap.getPixels(refSize, container, null);
- retValues[i] = new int[] {aft, aft, aft};
-
- } else {
- retValues[i] = gapAfter != gapBefore ? mergeSizes(gapAfter, gapBefore) : new int[] {defGapArr[0], defGapArr[1], defGapArr[2]};
- }
-
- if (specBefore != null && specBefore.isGapAfterPush() || specAfter != null && specAfter.isGapBeforePush())
- fillInPushGaps[i] = true;
- } else {
-
- if (wrapGapSize.isUnset()) {
- retValues[i] = new int[] {defGapArr[0], defGapArr[1], defGapArr[2]};
- } else {
- retValues[i] = wrapGapSize.getPixelSizes(refSize, container, null);
- }
- fillInPushGaps[i] = wrapGapSize.getGapPush();
- }
- }
- return retValues;
- }
-
- private static int[][] getGaps(ArrayList<CompWrap> compWraps, boolean isHor)
- {
- int compCount = compWraps.size();
- int[][] retValues = new int[compCount + 1][];
-
- retValues[0] = compWraps.get(0).getGaps(isHor, true);
- for (int i = 0; i < compCount; i++) {
- int[] gap1 = compWraps.get(i).getGaps(isHor, false);
- int[] gap2 = i < compCount - 1 ? compWraps.get(i + 1).getGaps(isHor, true) : null;
-
- retValues[i + 1] = mergeSizes(gap1, gap2);
- }
-
- return retValues;
- }
-
- private boolean hasDocks()
- {
- return (dockOffX > 0 || dockOffY > 0 || rowIndexes.last() > MAX_GRID || colIndexes.last() > MAX_GRID);
- }
-
- /**
- * @param specs The specs for the columns or rows. Last index will be used of <code>count</code> is greater than this array's length.
- * @param defGrow The default grow weight if the specs does not have anyone that will grow. Comes from "push" in the CC.
- * @param fss
- * @param groupsLists
- */
- private void adjustMinPrefForSpanningComps(DimConstraint[] specs, Float[] defGrow, FlowSizeSpec fss, ArrayList<LinkedDimGroup>[] groupsLists)
- {
- for (int r = 0; r < groupsLists.length; r++) {
- ArrayList<LinkedDimGroup> groups = groupsLists[r];
-
- for (int i = 0; i < groups.size(); i++) {
- LinkedDimGroup group = groups.get(i);
- if (group.span == 1)
- continue;
-
- int cSize = group.getMinPrefMax()[LayoutUtil.PREF];
- if (cSize == LayoutUtil.NOT_SET)
- continue;
-
- int rowSize = 0;
- int sIx = (r << 1) + 1;
- int len = Math.min((group.span << 1), fss.sizes.length - sIx) - 1;
- for (int j = sIx; j < sIx + len; j++) {
- int sz = fss.sizes[j][LayoutUtil.PREF];
- if (sz != LayoutUtil.NOT_SET)
- rowSize += sz;
- }
-
- if (rowSize < cSize) {
- for (int eag = 0, newRowSize = 0; eag < 4 && newRowSize < cSize; eag++)
- newRowSize = fss.expandSizes(specs, defGrow, cSize, sIx, len, LayoutUtil.PREF, eag);
- }
- }
- }
- }
-
- /** For one dimension divide the component wraps into logical groups. One group for component wraps that share a common something,
- * line the property to layout by base line.
- * @param isRows If rows, and not columns, are to be divided.
- * @return One <code>ArrayList<LinkedDimGroup></code> for every row/column.
- */
- private ArrayList<LinkedDimGroup>[] divideIntoLinkedGroups(boolean isRows)
- {
- boolean fromEnd = !(isRows ? lc.isTopToBottom() : LayoutUtil.isLeftToRight(lc, container));
- TreeSet<Integer> primIndexes = isRows ? rowIndexes : colIndexes;
- TreeSet<Integer> secIndexes = isRows ? colIndexes : rowIndexes;
- DimConstraint[] primDCs = (isRows ? rowConstr : colConstr).getConstaints();
-
- ArrayList<LinkedDimGroup>[] groupLists = new ArrayList[primIndexes.size()];
-
- int gIx = 0;
- for (Iterator<Integer> primIt = primIndexes.iterator(); primIt.hasNext();) {
- int i = primIt.next().intValue();
-
- DimConstraint dc;
- if (i >= -MAX_GRID && i <= MAX_GRID) { // If not dock cell
- dc = primDCs[i >= primDCs.length ? primDCs.length - 1 : i];
- } else {
- dc = DOCK_DIM_CONSTRAINT;
- }
-
- ArrayList<LinkedDimGroup> groupList = new ArrayList<LinkedDimGroup>(2);
- groupLists[gIx++] = groupList;
-
- for (Iterator<Integer> secIt = secIndexes.iterator(); secIt.hasNext();) {
- int j = secIt.next().intValue();
- Cell cell = isRows ? getCell(i, j) : getCell(j, i);
- if (cell == null || cell.compWraps.size() == 0)
- continue;
-
- int span = (isRows ? cell.spany : cell.spanx);
- if (span > 1)
- span = convertSpanToSparseGrid(i, span, primIndexes);
-
- boolean isPar = cell.flowx == isRows;
-
- if ((isPar == false && cell.compWraps.size() > 1) || span > 1) {
-
- int linkType = isPar ? LinkedDimGroup.TYPE_PARALLEL : LinkedDimGroup.TYPE_SERIAL;
- LinkedDimGroup lg = new LinkedDimGroup("p," + j, span, linkType, !isRows, fromEnd);
- lg.setCompWraps(cell.compWraps);
- groupList.add(lg);
- } else {
- for (int cwIx = 0; cwIx < cell.compWraps.size(); cwIx++) {
- CompWrap cw = cell.compWraps.get(cwIx);
- boolean rowBaselineAlign = (isRows && dc.getAlignOrDefault(!isRows) == UnitValue.BASELINE_IDENTITY);
-
- String linkCtx = cw.getLinkContext(rowBaselineAlign);
-
- // Find a group with same link context and put it in that group.
- boolean foundList = false;
- for (int glIx = 0, lastGl = groupList.size() - 1; glIx <= lastGl ; glIx++) {
- LinkedDimGroup group = groupList.get(glIx);
- if (group.linkCtx == linkCtx || linkCtx != null && linkCtx.equals(group.linkCtx)) {
- group.addCompWrap(cw);
- foundList = true;
- break;
- }
- }
-
- // If none found and at last add a new group.
- if (foundList == false) {
-
- int linkType = LinkedDimGroup.TYPE_PARALLEL;
- if (isRows && cw.isBaselineAlign(rowBaselineAlign))
- linkType = LinkedDimGroup.TYPE_BASELINE;
-
- LinkedDimGroup lg = new LinkedDimGroup(linkCtx, 1, linkType, !isRows, fromEnd);
- lg.addCompWrap(cw);
- groupList.add(lg);
- }
- }
- }
- }
- }
- return groupLists;
- }
-
- /** Spanning is specified in the uncompressed grid number. They can for instance be more than 60000 for the outer
- * edge dock grid cells. When the grid is compressed and indexed after only the cells that area occupied the span
- * is erratic. This method use the row/col indexes and corrects the span to be correct for the compressed grid.
- * @param span The span un the uncompressed grid. <code>LayoutUtil.INF</code> will be interpreted to span the rest
- * of the column/row excluding the surrounding docking components.
- * @param indexes The indexes in the correct dimension.
- * @return The converted span.
- */
- private int convertSpanToSparseGrid(int curIx, int span, TreeSet<Integer> indexes)
- {
- int lastIx = curIx + span;
- int retSpan = 1;
-
- for (Iterator<Integer> it = indexes.iterator(); it.hasNext();) {
- int ix = it.next();
- if (ix <= curIx)
- continue; // We have not arrive to the correct index yet
-
- if (ix >= lastIx)
- break;
-
- retSpan++;
- }
- return retSpan;
- }
-
- private final boolean isCellFree(int r, int c, ArrayList<int[]> occupiedRects)
- {
- if (getCell(r, c) != null)
- return false;
-
- for (int i = 0; i < occupiedRects.size(); i++) {
- int[] rect = occupiedRects.get(i);
- if (rect[0] <= c && rect[1] <= r && rect[0] + rect[2] > c && rect[1] + rect[3] > r)
- return false;
- }
- return true;
- }
-
- private Cell getCell(int r, int c)
- {
- return grid.get(new Integer((r << 16) + c));
- }
-
- private void setCell(int r, int c, Cell cell)
- {
- if (c < 0 || c > MAX_GRID || r < 0 || r > MAX_GRID)
- throw new IllegalArgumentException("Cell position out of bounds. row: " + r + ", col: " + c);
-
- rowIndexes.add(new Integer(r));
- colIndexes.add(new Integer(c));
-
- grid.put(new Integer((r << 16) + c), cell);
- }
-
- /** Adds a docking cell. That cell is outside the normal cell indexes.
- * @param dockInsets The current dock insets. Will be updated!
- * @param side top == 0, left == 1, bottom = 2, right = 3.
- * @param cw The compwrap to put in a cell and add.
- */
- private void addDockingCell(int[] dockInsets, int side, CompWrap cw)
- {
- int r, c, spanx = 1, spany = 1;
- switch (side) {
- case 0:
- case 2:
- r = side == 0 ? dockInsets[0]++ : dockInsets[2]--;
- c = dockInsets[1];
- spanx = dockInsets[3] - dockInsets[1] + 1; // The +1 is for cell 0.
- colIndexes.add(new Integer(dockInsets[3])); // Make sure there is a receiving cell
- break;
-
- case 1:
- case 3:
- c = side == 1 ? dockInsets[1]++ : dockInsets[3]--;
- r = dockInsets[0];
- spany = dockInsets[2] - dockInsets[0] + 1; // The +1 is for cell 0.
- rowIndexes.add(new Integer(dockInsets[2])); // Make sure there is a receiving cell
- break;
-
- default:
- throw new IllegalArgumentException("Internal error 123.");
- }
-
- rowIndexes.add(new Integer(r));
- colIndexes.add(new Integer(c));
-
- grid.put(new Integer((r << 16) + c), new Cell(cw, spanx, spany, spanx > 1));
- }
-
- /** A simple representation of a cell in the grid. Contains a number of component wraps and if they span more than one cell.
- */
- private static class Cell
- {
- private final int spanx, spany;
- private final boolean flowx;
- private final ArrayList<CompWrap> compWraps = new ArrayList<CompWrap>(1);
-
- private boolean hasTagged = false; // If one or more components have styles and need to be checked by the component sorter
-
- private Cell(CompWrap cw)
- {
- this(cw, 1, 1, true);
- }
-
- private Cell(int spanx, int spany, boolean flowx)
- {
- this(null, spanx, spany, flowx);
- }
-
- private Cell(CompWrap cw, int spanx, int spany, boolean flowx)
- {
- if (cw != null)
- compWraps.add(cw);
- this.spanx = spanx;
- this.spany = spany;
- this.flowx = flowx;
- }
- }
-
- /** A number of component wraps that share a layout "something" <b>in one dimension</b>
- */
- private static class LinkedDimGroup
- {
- private static final int TYPE_SERIAL = 0;
- private static final int TYPE_PARALLEL = 1;
- private static final int TYPE_BASELINE = 2;
-
- private final String linkCtx;
- private final int span;
- private final int linkType;
- private final boolean isHor, fromEnd;
-
- private ArrayList<CompWrap> _compWraps = new ArrayList<CompWrap>(4);
-
- private int[] sizes = null;
- private int lStart = 0, lSize = 0; // Currently mostly for debug painting
-
- private LinkedDimGroup(String linkCtx, int span, int linkType, boolean isHor, boolean fromEnd)
- {
- this.linkCtx = linkCtx;
- this.span = span;
- this.linkType = linkType;
- this.isHor = isHor;
- this.fromEnd = fromEnd;
- }
-
- private void addCompWrap(CompWrap cw)
- {
- _compWraps.add(cw);
- sizes = null;
- }
-
- private void setCompWraps(ArrayList<CompWrap> cws)
- {
- if (_compWraps != cws) {
- _compWraps = cws;
- sizes = null;
- }
- }
-
- private void layout(DimConstraint dc, int start, int size, int spanCount)
- {
- lStart = start;
- lSize = size;
-
- if (_compWraps.size() == 0)
- return;
-
- ContainerWrapper parent = _compWraps.get(0).comp.getParent();
- if (linkType == TYPE_PARALLEL) {
- layoutParallel(parent, _compWraps, dc, start, size, isHor, spanCount, fromEnd);
- } else if (linkType == TYPE_BASELINE) {
- layoutBaseline(parent, _compWraps, dc, start, size, LayoutUtil.PREF, spanCount);
- } else {
- layoutSerial(parent, _compWraps, dc, start, size, isHor, spanCount, fromEnd);
- }
- }
-
- /** Returns the min/pref/max sizes for this cell. Returned array <b>must not be altered</b>
- * @return A shared min/pref/max array of sizes. Always of length 3 and never <code>null</code>. Will always be of type STATIC and PIXEL.
- */
- private int[] getMinPrefMax()
- {
- if (sizes == null && _compWraps.size() > 0) {
- sizes = new int[3];
- for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.PREF; sType++) {
- if (linkType == TYPE_PARALLEL) {
- sizes[sType] = getTotalSizeParallel(_compWraps, sType, isHor);
- } else if (linkType == TYPE_BASELINE) {
- int[] aboveBelow = getBaselineAboveBelow(_compWraps, sType, false);
- sizes[sType] = aboveBelow[0] + aboveBelow[1];
- } else {
- sizes[sType] = getTotalSizeSerial(_compWraps, sType, isHor);
- }
- }
- sizes[LayoutUtil.MAX] = LayoutUtil.INF;
- }
- return sizes;
- }
- }
-
- /** Wraps a {@link java.awt.Component} together with its constraint. Caches a lot of information about the component so
- * for instance not the preferred size has to be calculated more than once.
- */
- private final static class CompWrap
- {
- private final ComponentWrapper comp;
- private final CC cc;
- private final UnitValue[] pos;
- private int[][] gaps; // [top,left(actually before),bottom,right(actually after)][min,pref,max]
-
- private final int[] horSizes = new int[3];
- private final int[] verSizes = new int[3];
-
- private int x = LayoutUtil.NOT_SET, y = LayoutUtil.NOT_SET, w = LayoutUtil.NOT_SET, h = LayoutUtil.NOT_SET;
-
- private int forcedPushGaps = 0; // 1 == before, 2 = after. Bitwise.
-
- private CompWrap(ComponentWrapper c, CC cc, int eHideMode, UnitValue[] pos, BoundSize[] callbackSz)
- {
- this.comp = c;
- this.cc = cc;
- this.pos = pos;
-
- if (eHideMode <= 0) {
- BoundSize hBS = (callbackSz != null && callbackSz[0] != null) ? callbackSz[0] : cc.getHorizontal().getSize();
- BoundSize vBS = (callbackSz != null && callbackSz[1] != null) ? callbackSz[1] : cc.getVertical().getSize();
-
- for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) {
- horSizes[i] = getSize(hBS, i, true);
- verSizes[i] = getSize(vBS, i, false);
- }
-
- correctMinMax(horSizes);
- correctMinMax(verSizes);
- }
-
- if (eHideMode > 1) {
- gaps = new int[4][];
- for (int i = 0; i < gaps.length; i++)
- gaps[i] = new int[3];
- }
- }
-
- private final int getSize(BoundSize uvs, int sizeType, boolean isHor)
- {
- if (uvs == null || uvs.getSize(sizeType) == null) {
- switch(sizeType) {
- case LayoutUtil.MIN:
- return isHor ? comp.getMinimumWidth() : comp.getMinimumHeight();
- case LayoutUtil.PREF:
- return isHor ? comp.getPreferredWidth() : comp.getPreferredHeight();
- default:
- return isHor ? comp.getMaximumWidth() : comp.getMaximumHeight();
- }
- }
-
- ContainerWrapper par = comp.getParent();
- return uvs.getSize(sizeType).getPixels(isHor ? par.getWidth() : par.getHeight(), par, comp);
- }
-
- private final void calcGaps(ComponentWrapper before, CC befCC, ComponentWrapper after, CC aftCC, String tag, boolean flowX, boolean isLTR)
- {
- ContainerWrapper par = comp.getParent();
- int parW = par.getWidth();
- int parH = par.getHeight();
-
- BoundSize befGap = before != null ? (flowX ? befCC.getHorizontal() : befCC.getVertical()).getGapAfter() : null;
- BoundSize aftGap = after != null ? (flowX ? aftCC.getHorizontal() : aftCC.getVertical()).getGapBefore() : null;
-
- mergeGapSizes(cc.getVertical().getComponentGaps(par, comp, befGap, (flowX ? null : before), tag, parH, 0, isLTR), false, true);
- mergeGapSizes(cc.getHorizontal().getComponentGaps(par, comp, befGap, (flowX ? before : null), tag, parW, 1, isLTR), true, true);
- mergeGapSizes(cc.getVertical().getComponentGaps(par, comp, aftGap, (flowX ? null : after), tag, parH, 2, isLTR), false, false);
- mergeGapSizes(cc.getHorizontal().getComponentGaps(par, comp, aftGap, (flowX ? after : null), tag, parW, 3, isLTR), true, false);
- }
-
- private final void setDimBounds(int start, int size, boolean isHor)
- {
- if (isHor) {
- x = start;
- w = size;
- } else {
- y = start;
- h = size;
- }
- }
-
- private final boolean isPushGap(boolean isHor, boolean isBefore)
- {
- if (isHor && ((isBefore ? 1 : 2) & forcedPushGaps) != 0)
- return true; // Forced
-
- DimConstraint dc = cc.getDimConstraint(isHor);
- BoundSize s = isBefore ? dc.getGapBefore() : dc.getGapAfter();
- return s != null && s.getGapPush();
- }
-
- /**
- * @return If the preferred size have changed because of the new bounds (needed for SWT only)
- */
- private final boolean transferBounds(boolean checkPrefChange)
- {
- comp.setBounds(x, y, w, h);
-
- if (checkPrefChange && w != horSizes[LayoutUtil.PREF]) {
- BoundSize vSz = cc.getVertical().getSize();
- if ((vSz == null || vSz.getPreferred() == null)) {
- if (comp.getPreferredHeight() != verSizes[LayoutUtil.PREF]) {
- //System.out.println(comp.getComponent() + "oldPrefH: " + verSizes[LayoutUtil.PREF] + ", new: " + comp.getPreferredHeight());
- return true;
- }
- }
- }
-
- return false;
- }
-
- private final void setSizes(int[] sizes, boolean isHor)
- {
- if (sizes == null)
- return;
-
- int[] s = isHor ? horSizes : verSizes;
- for (int i = 0; i < 3; i++)
- s[i] = sizes[i];
- }
-
- private void setGaps(int[] minPrefMax, int ix)
- {
- if (gaps == null)
- gaps = new int[][] {null, null, null, null};
-
- gaps[ix] = minPrefMax;
- }
-
- private final void mergeGapSizes(int[] sizes, boolean isHor, boolean isTL)
- {
- if (gaps == null)
- gaps = new int[][] {null, null, null, null};
-
- if (sizes == null)
- return;
-
- int gapIX = getGapIx(isHor, isTL);
- int[] oldGaps = gaps[gapIX];
- if (oldGaps == null) {
- oldGaps = new int[] {0, 0, LayoutUtil.INF};
- gaps[gapIX] = oldGaps;
- }
-
- oldGaps[LayoutUtil.MIN] = Math.max(sizes[LayoutUtil.MIN], oldGaps[LayoutUtil.MIN]);
- oldGaps[LayoutUtil.PREF] = Math.max(sizes[LayoutUtil.PREF], oldGaps[LayoutUtil.PREF]);
- oldGaps[LayoutUtil.MAX] = Math.min(sizes[LayoutUtil.MAX], oldGaps[LayoutUtil.MAX]);
- }
-
- private final int getGapIx(boolean isHor, boolean isTL)
- {
- return isHor ? (isTL ? 1 : 3) : (isTL ? 0 : 2);
- }
-
- private final String getLinkContext(boolean defBaseline)
- {
- return isBaselineAlign(defBaseline) ? "baseline" : null;
- }
-
- private final int getSizeInclGaps(int sizeType, boolean isHor)
- {
- return filter(sizeType, getGapBefore(sizeType, isHor) + getSize(sizeType, isHor) + getGapAfter(sizeType, isHor));
- }
-
- private final int getSize(int sizeType, boolean isHor)
- {
- return filter(sizeType, isHor ? horSizes[sizeType] : verSizes[sizeType]);
- }
-
- private final int getGapBefore(int sizeType, boolean isHor)
- {
- int[] gaps = getGaps(isHor, true);
- return gaps != null ? filter(sizeType, gaps[sizeType]) : 0;
- }
-
- private final int getGapAfter(int sizeType, boolean isHor)
- {
- int[] gaps = getGaps(isHor, false);
- return gaps != null ? filter(sizeType, gaps[sizeType]) : 0;
- }
-
- private final int[] getGaps(boolean isHor, boolean isTL)
- {
- return gaps[getGapIx(isHor, isTL)];
- }
-
- private final int filter(int sizeType, int size)
- {
- if (size == LayoutUtil.NOT_SET)
- return sizeType != LayoutUtil.MAX ? 0 : LayoutUtil.INF;
- return constrainSize(size);
- }
-
- private final boolean isBaselineAlign(boolean defValue)
- {
- Float g = cc.getVertical().getGrow();
- if (g != null && g.intValue() != 0)
- return false;
-
- UnitValue al = cc.getVertical().getAlign();
- return comp.hasBaseline() && (al != null ? al == UnitValue.BASELINE_IDENTITY : defValue);
- }
-
- private final int getBaseline(int sizeType)
- {
- return comp.getBaseline(getSize(sizeType, true), getSize(sizeType, false));
- }
- }
-
- //***************************************************************************************
- //* Helper Methods
- //***************************************************************************************
-
- private static void layoutBaseline(ContainerWrapper parent, ArrayList<CompWrap> compWraps, DimConstraint dc, int start, int size, int sizeType, int spanCount)
- {
- int[] aboveBelow = getBaselineAboveBelow(compWraps, sizeType, true);
- int blRowSize = aboveBelow[0] + aboveBelow[1];
-
- CC cc = compWraps.get(0).cc;
-
- // Align for the whole baseline component array
- UnitValue align = cc.getVertical().getAlign();
- if (spanCount == 1 && align == null)
- align = dc.getAlignOrDefault(false);
- if (align == UnitValue.BASELINE_IDENTITY)
- align = UnitValue.CENTER;
-
- int offset = start + aboveBelow[0] + (align != null ? Math.max(0, align.getPixels(size - blRowSize, parent, null)) : 0);
- for (int i = 0, iSz = compWraps.size(); i < iSz; i++) {
- CompWrap cw = compWraps.get(i);
- cw.y += offset;
-
- if (cw.y + cw.h > start + size)
- cw.h = start + size - cw.y;
- }
- }
-
- private static void layoutSerial(ContainerWrapper parent, ArrayList<CompWrap> compWraps, DimConstraint dc, int start, int size, boolean isHor, int spanCount, boolean fromEnd)
- {
- FlowSizeSpec fss = mergeSizesGapsAndResConstrs(
- getComponentResizeConstraints(compWraps, isHor),
- getComponentGapPush(compWraps, isHor),
- getComponentSizes(compWraps, isHor),
- getGaps(compWraps, isHor),
- 0, null);
-
- Float[] growW = dc.isFill() ? GROW_100 : null;
- int[] sizes = LayoutUtil.calculateSerial(fss.sizes, fss.resConstsInclGaps, growW, LayoutUtil.PREF, size);
- setCompWrapBounds(parent, sizes, compWraps, dc.getAlignOrDefault(isHor), start, size, isHor, fromEnd);
- }
-
- private static void setCompWrapBounds(ContainerWrapper parent, int[] allSizes, ArrayList<CompWrap> compWraps, UnitValue rowAlign, int start, int size, boolean isHor, boolean fromEnd)
- {
- int totSize = LayoutUtil.sum(allSizes);
- CC cc = compWraps.get(0).cc;
- UnitValue align = correctAlign(cc, rowAlign, isHor, fromEnd);
-
- int cSt = start;
- int slack = size - totSize;
- if (slack > 0 && align != null) {
- int al = Math.min(slack, Math.max(0, align.getPixels(slack, parent, null)));
- cSt += (fromEnd ? -al : al);
- }
-
- for (int i = 0, bIx = 0, iSz = compWraps.size(); i < iSz; i++) {
- CompWrap cw = compWraps.get(i);
- if (fromEnd ) {
- cSt -= allSizes[bIx++];
- cw.setDimBounds(cSt - allSizes[bIx], allSizes[bIx], isHor);
- cSt -= allSizes[bIx++];
- } else {
- cSt += allSizes[bIx++];
- cw.setDimBounds(cSt, allSizes[bIx], isHor);
- cSt += allSizes[bIx++];
- }
- }
- }
-
- private static void layoutParallel(ContainerWrapper parent, ArrayList<CompWrap> compWraps, DimConstraint dc, int start, int size, boolean isHor, int spanCount, boolean fromEnd)
- {
- int[][] sizes = new int[compWraps.size()][]; // [compIx][gapBef,compSize,gapAft]
-
- for (int i = 0; i < sizes.length; i++) {
- CompWrap cw = compWraps.get(i);
-
- DimConstraint cDc = cw.cc.getDimConstraint(isHor);
-
- ResizeConstraint[] resConstr = new ResizeConstraint[] {
- cw.isPushGap(isHor, true) ? GAP_RC_CONST_PUSH : GAP_RC_CONST,
- cDc.resize,
- cw.isPushGap(isHor, false) ? GAP_RC_CONST_PUSH : GAP_RC_CONST,
- };
-
- int[][] sz = new int[][] {
- cw.getGaps(isHor, true), (isHor ? cw.horSizes : cw.verSizes), cw.getGaps(isHor, false)
- };
-
- Float[] growW = dc.isFill() ? GROW_100 : null;
-
- sizes[i] = LayoutUtil.calculateSerial(sz, resConstr, growW, LayoutUtil.PREF, size);
- }
-
- UnitValue rowAlign = dc.getAlignOrDefault(isHor);
- setCompWrapBounds(parent, sizes, compWraps, rowAlign, start, size, isHor, fromEnd);
- }
-
- private static void setCompWrapBounds(ContainerWrapper parent, int[][] sizes, ArrayList<CompWrap> compWraps, UnitValue rowAlign, int start, int size, boolean isHor, boolean fromEnd)
- {
- for (int i = 0; i < sizes.length; i++) {
- CompWrap cw = compWraps.get(i);
-
- UnitValue align = correctAlign(cw.cc, rowAlign, isHor, fromEnd);
-
- int[] cSizes = sizes[i];
- int gapBef = cSizes[0];
- int cSize = cSizes[1]; // No Math.min(size, cSizes[1]) here!
- int gapAft = cSizes[2];
-
- int cSt = fromEnd ? start - gapBef : start + gapBef;
- int slack = size - cSize - gapBef - gapAft;
- if (slack > 0 && align != null) {
- int al = Math.min(slack, Math.max(0, align.getPixels(slack, parent, null)));
- cSt += (fromEnd ? -al : al);
- }
-
- cw.setDimBounds(fromEnd ? cSt - cSize : cSt, cSize, isHor);
- }
- }
-
- private static UnitValue correctAlign(CC cc, UnitValue rowAlign, boolean isHor, boolean fromEnd)
- {
- UnitValue align = (isHor ? cc.getHorizontal() : cc.getVertical()).getAlign();
- if (align == null)
- align = rowAlign;
- if (align == UnitValue.BASELINE_IDENTITY)
- align = UnitValue.CENTER;
-
- if (fromEnd) {
- if (align == UnitValue.LEFT)
- align = UnitValue.RIGHT;
- else if (align == UnitValue.RIGHT)
- align = UnitValue.LEFT;
- }
- return align;
- }
-
- private static int[] getBaselineAboveBelow(ArrayList<CompWrap> compWraps, int sType, boolean centerBaseline)
- {
- int maxAbove = Short.MIN_VALUE;
- int maxBelow = Short.MIN_VALUE;
- for (int i = 0, iSz = compWraps.size(); i < iSz; i++) {
- CompWrap cw = compWraps.get(i);
-
- int height = cw.getSize(sType, false);
- if (height >= LayoutUtil.INF)
- return new int[] {LayoutUtil.INF / 2, LayoutUtil.INF / 2};
-
- int baseline = cw.getBaseline(sType);
- int above = baseline + cw.getGapBefore(sType, false);
- maxAbove = Math.max(above, maxAbove);
- maxBelow = Math.max(height - baseline + cw.getGapAfter(sType, false), maxBelow);
-
- if (centerBaseline)
- cw.setDimBounds(-baseline, height, false);
- }
- return new int[] {maxAbove, maxBelow};
- }
-
- private static int getTotalSizeParallel(ArrayList<CompWrap> compWraps, int sType, boolean isHor)
- {
- int size = sType == LayoutUtil.MAX ? LayoutUtil.INF : 0;
-
- for (int i = 0, iSz = compWraps.size(); i < iSz; i++) {
- CompWrap cw = compWraps.get(i);
- int cwSize = cw.getSizeInclGaps(sType, isHor);
- if (cwSize >= LayoutUtil.INF)
- return LayoutUtil.INF;
-
- if (sType == LayoutUtil.MAX ? cwSize < size : cwSize > size)
- size = cwSize;
- }
- return constrainSize(size);
- }
-
- private static final int getTotalSizeSerial(ArrayList<CompWrap> compWraps, int sType, boolean isHor)
- {
- int totSize = 0;
- for (int i = 0, iSz = compWraps.size(), lastGapAfter = 0; i < iSz; i++) {
- CompWrap wrap = compWraps.get(i);
- int gapBef = wrap.getGapBefore(sType, isHor);
- if (gapBef > lastGapAfter)
- totSize += gapBef - lastGapAfter;
-
- totSize += wrap.getSize(sType, isHor);
- totSize += (lastGapAfter = wrap.getGapAfter(sType, isHor));
-
- if (totSize >= LayoutUtil.INF)
- return LayoutUtil.INF;
- }
- return constrainSize(totSize);
- }
-
- private static final int getTotalGroupsSizeParallel(ArrayList<LinkedDimGroup> groups, int sType, boolean countSpanning)
- {
- int size = sType == LayoutUtil.MAX ? LayoutUtil.INF : 0;
- for (int i = 0, iSz = groups.size(); i < iSz; i++) {
- LinkedDimGroup group = groups.get(i);
- if (countSpanning || group.span == 1) {
- int grpSize = group.getMinPrefMax()[sType];
- if (grpSize >= LayoutUtil.INF)
- return LayoutUtil.INF;
-
- if (sType == LayoutUtil.MAX ? grpSize < size : grpSize > size)
- size = grpSize;
- }
- }
- return constrainSize(size);
- }
-
- /**
- * @param compWraps
- * @param isHor
- * @return Might contain LayoutUtil.NOT_SET
- */
- private static int[][] getComponentSizes(ArrayList<CompWrap> compWraps, boolean isHor)
- {
- int[][] compSizes = new int[compWraps.size()][];
- for (int i = 0; i < compSizes.length; i++) {
- CompWrap cw = compWraps.get(i);
- compSizes[i] = isHor ? cw.horSizes : cw.verSizes;
- }
- return compSizes;
- }
-
- /** Merges sizes and gaps together with Resize Constraints. For gaps {@link #GAP_RC_CONST} is used.
- * @param resConstr One resize constriant for every row/component. Can be lesser in length and the last element should be used for missing elements.
- * @param gapPush If the corresponding gap should be considered pushing and thus want to take free space if left over. Should be one more than resConstrs!
- * @param minPrefMaxSizes The sizes (min/pref/max) for every row/component.
- * @param gapSizes The gaps before and after each row/component packed in one double sized array.
- * @param refSize The reference size to get the gap in pixels.
- * @param parent The parent used to get the gap in pixels.
- * @return A holder for the merged values.
- */
- private static FlowSizeSpec mergeSizesGapsAndResConstrs(ResizeConstraint[] resConstr, boolean[] gapPush, int[][] minPrefMaxSizes, int[][] gapSizes, int refSize, ContainerWrapper parent)
- {
- int[][] sizes = new int[(minPrefMaxSizes.length << 1) + 1][]; // Make room for gaps around.
- ResizeConstraint[] resConstsInclGaps = new ResizeConstraint[sizes.length];
-
- sizes[0] = gapSizes[0];
- for (int i = 0, crIx = 1; i < minPrefMaxSizes.length; i++, crIx += 2) {
-
- // Component bounds and constraints
- resConstsInclGaps[crIx] = resConstr[i];
- sizes[crIx] = minPrefMaxSizes[i];
-
- sizes[crIx + 1] = gapSizes[i + 1];
-
- if (sizes[crIx - 1] != null)
- resConstsInclGaps[crIx - 1] = gapPush[i < gapPush.length ? i : gapPush.length - 1] ? GAP_RC_CONST_PUSH : GAP_RC_CONST;
-
- if (i == (minPrefMaxSizes.length - 1) && sizes[crIx + 1] != null)
- resConstsInclGaps[crIx + 1] = gapPush[(i + 1) < gapPush.length ? (i + 1) : gapPush.length - 1] ? GAP_RC_CONST_PUSH : GAP_RC_CONST;
- }
-
- // Check for null and set it to 0, 0, 0.
- for (int i = 0; i < sizes.length; i++) {
- if (sizes[i] == null)
- sizes[i] = new int[3];
- }
-
- return new FlowSizeSpec(sizes, resConstsInclGaps);
- }
-
- private static final int[] mergeSizes(int[] oldValues, int[] newValues)
- {
- if (oldValues == null)
- return newValues;
-
- if (newValues == null)
- return oldValues;
-
- int[] ret = new int[oldValues.length];
- for (int i = 0; i < ret.length; i++)
- ret[i] = mergeSizes(oldValues[i], newValues[i], true);
-
- return ret;
- }
-
- private static final int mergeSizes(int oldValue, int newValue, boolean toMax)
- {
- if (oldValue == LayoutUtil.NOT_SET || oldValue == newValue)
- return newValue;
-
- if (newValue == LayoutUtil.NOT_SET)
- return oldValue;
-
- return toMax != oldValue > newValue ? newValue : oldValue;
- }
-
- private static final int constrainSize(int s)
- {
- return s > 0 ? (s < LayoutUtil.INF ? s : LayoutUtil.INF) : 0;
- }
-
- private static final void correctMinMax(int s[])
- {
- if (s[LayoutUtil.MIN] > s[LayoutUtil.MAX])
- s[LayoutUtil.MIN] = s[LayoutUtil.MAX]; // Since MAX is almost always explicitly set use tha
-
- if (s[LayoutUtil.PREF] < s[LayoutUtil.MIN])
- s[LayoutUtil.PREF] = s[LayoutUtil.MIN];
-
- if (s[LayoutUtil.PREF] > s[LayoutUtil.MAX])
- s[LayoutUtil.PREF] = s[LayoutUtil.MAX];
- }
-
- private static final class FlowSizeSpec
- {
- private final int[][] sizes;
- private final ResizeConstraint[] resConstsInclGaps;
-
- private FlowSizeSpec(int[][] sizes, ResizeConstraint[] resConstsInclGaps)
- {
- this.sizes = sizes;
- this.resConstsInclGaps = resConstsInclGaps;
- }
-
- /**
- * @param specs The specs for the columns or rows. Last index will be used of <code>fromIx + len</code> is greater than this array's length.
- * @param targetSize The size to try to meat.
- * @param defGrow The default grow weight if the specs does not have anyone that will grow. Comes from "push" in the CC.
- * @param fromIx
- * @param len
- * @param sizeType
- * @param eagerness How eager the algorithm should be to try to expand the sizes.
- * <ul>
- * <li>0 - Grow only rows/columns which has the <code>sizeType</code> set to be the containing components AND which has a grow weight > 0.
- * <li>1 - Grow only rows/columns which has the <code>sizeType</code> set to be the containing components AND which has a grow weight > 0 OR unspecified.
- * <li>2 - Grow all rows/columns that has a grow weight > 0.
- * <li>3 - Grow all rows/columns that has a grow weight > 0 OR unspecified.
- * </ul>
- * @return The new size.
- */
- private final int expandSizes(DimConstraint[] specs, Float[] defGrow, int targetSize, int fromIx, int len, int sizeType, int eagerness)
- {
- ResizeConstraint[] resConstr = new ResizeConstraint[len];
- int[][] sizesToExpand = new int[len][];
- for (int i = 0; i < len; i++) {
- int size = sizes[i + fromIx][sizeType];
- sizesToExpand[i] = new int[] {size, size, sizes[i + fromIx][LayoutUtil.MAX]};
-
- if (eagerness <= 1 && i % 2 == 0) { // // (i % 2 == 0) means only odd indexes, which is only rows/col indexes and not gaps.
- int cIx = (i + fromIx - 1) >> 1;
- DimConstraint spec = (DimConstraint) LayoutUtil.getIndexSafe(specs, cIx);
-
- if ( (sizeType == LayoutUtil.MIN && spec.getSize() != null && spec.getSize().getMin() != null && spec.getSize().getMin().getUnit() != UnitValue.MIN_SIZE) ||
- (sizeType == LayoutUtil.PREF && spec.getSize() != null && spec.getSize().getPreferred() != null && spec.getSize().getPreferred().getUnit() != UnitValue.PREF_SIZE)) {
- continue;
- }
- }
- resConstr[i] = (ResizeConstraint) LayoutUtil.getIndexSafe(resConstsInclGaps, i + fromIx);
- }
-
- Float[] growW = (eagerness == 1 || eagerness == 3) ? extractSubArray(specs, defGrow, fromIx, len): null;
- int[] newSizes = LayoutUtil.calculateSerial(sizesToExpand, resConstr, growW, sizeType, targetSize);
- int newSize = 0;
-
- for (int i = 0; i < len; i++) {
- int s = newSizes[i];
- sizes[i + fromIx][sizeType] = s;
- newSize += s;
- }
- return newSize;
- }
- }
-
- private static Float[] extractSubArray(DimConstraint[] specs, Float[] arr, int ix, int len)
- {
- if (arr == null || arr.length < ix + len) {
- Float[] growLastArr = new Float[len];
-
- // Handle a group where some rows (first one/few and/or last one/few) are docks.
- for (int i = ix + len - 1; i >= 0; i -= 2) {
- int specIx = (i >> 1);
- if (specs[specIx] != DOCK_DIM_CONSTRAINT) {
- growLastArr[i - ix] = ResizeConstraint.WEIGHT_100;
- return growLastArr;
- }
- }
- return growLastArr;
- }
-
- Float[] newArr = new Float[len];
- for (int i = 0; i < len; i++)
- newArr[i] = arr[ix + i];
- return newArr;
- }
-
- private static WeakHashMap[] PARENT_ROWCOL_SIZES_MAP = null;
- static synchronized void putSizesAndIndexes(Object parComp, int[] sizes, int[] ixArr, boolean isRows)
- {
- if (PARENT_ROWCOL_SIZES_MAP == null) // Lazy since only if designing in IDEs
- PARENT_ROWCOL_SIZES_MAP = new WeakHashMap[] {new WeakHashMap(4), new WeakHashMap(4)};
-
- PARENT_ROWCOL_SIZES_MAP[isRows ? 0 : 1].put(parComp, new int[][] {ixArr, sizes});
- }
-
- static synchronized int[][] getSizesAndIndexes(Object parComp, boolean isRows)
- {
- if (PARENT_ROWCOL_SIZES_MAP == null)
- return null;
-
- return (int[][]) PARENT_ROWCOL_SIZES_MAP[isRows ? 0 : 1].get(parComp);
- }
-}
+package net.miginfocom.layout; + + +import java.util.*; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** Holds components in a grid. Does most of the logic behind the layout manager. + */ +public final class Grid +{ + public static final boolean TEST_GAPS = true; + + private static final Float[] GROW_100 = new Float[] {ResizeConstraint.WEIGHT_100}; + + private static final DimConstraint DOCK_DIM_CONSTRAINT = new DimConstraint(); + static { + DOCK_DIM_CONSTRAINT.setGrowPriority(0); + } + + /** This is the maximum grid position for "normal" components. Docking components use the space out to + * <code>MAX_DOCK_GRID</code> and below 0. + */ + private static final int MAX_GRID = 30000; + + /** Docking components will use the grid coordinates <code>-MAX_DOCK_GRID -> 0</code> and <code>MAX_GRID -> MAX_DOCK_GRID</code>. + */ + private static final int MAX_DOCK_GRID = 32767; + + /** A constraint used for gaps. + */ + private static final ResizeConstraint GAP_RC_CONST = new ResizeConstraint(200, ResizeConstraint.WEIGHT_100, 50, null); + private static final ResizeConstraint GAP_RC_CONST_PUSH = new ResizeConstraint(200, ResizeConstraint.WEIGHT_100, 50, ResizeConstraint.WEIGHT_100); + + /** The constraints. Never <code>null</code>. + */ + private final LC lc; + + /** The parent that is layout out and this grid is done for. Never <code>null</code>. + */ + private final ContainerWrapper container; + + /** An x, y array implemented as a sparse array to accomodate for any grid size without wasting memory (or rather 15 bit (0-MAX_GRID * 0-MAX_GRID). + */ + private final LinkedHashMap<Integer, Cell> grid = new LinkedHashMap<Integer, Cell>(); // [(y << 16) + x] -> Cell. null key for absolute positioned compwraps + + private HashMap<Integer, BoundSize> wrapGapMap = null; // Row or Column index depending in the dimension that "raps". Normally row indexes but may be column indexes if "flowy". 0 means before first row/col. + + /** The size of the grid. Row count and column count. + */ + private final TreeSet<Integer> rowIndexes = new TreeSet<Integer>(), colIndexes = new TreeSet<Integer>(); + + /** The row and column specifications. + */ + private final AC rowConstr, colConstr; + + /** The in the constructor calculated min/pref/max sizes of the rows and columns. + */ + private FlowSizeSpec colFlowSpecs = null, rowFlowSpecs = null; + + /** Components that are connectione in one dimension (such as baseline alignment for instance) are grouped together and stored here. + * One for each row/column. + */ + private ArrayList<LinkedDimGroup>[] colGroupLists, rowGroupLists; //[(start)row/col number] + + /** The in the constructor calculated min/pref/max size of the whole grid. + */ + private int[] width = null, height = null; + + /** If debug is on contains the bounds for things to paint when calling {@link ContainerWrapper#paintDebugCell(int, int, int, int)} + */ + private ArrayList<int[]> debugRects = null; // [x, y, width, height] + + /** If any of the absolute coordinates for component bounds has links the name of the target is in this Set. + * Since it requires some memory and computations this is checked at the creation so that + * the link information is only created if needed later. + * <p> + * The boolean is true for groups id:s and null for normal id:s. + */ + private HashMap<String, Boolean> linkTargetIDs = null; + + private final int dockOffY, dockOffX; + + private final Float[] growXs, growYs; + + private final ArrayList<LayoutCallback> callbackList; + + /** Constructor. + * @param container The container that will be laid out. + * @param lc The form flow constraints. + * @param rowConstr The rows specifications. If more cell rows are required, the last element will be used for when there is no corresponding element in this array. + * @param colConstr The columns specifications. If more cell rows are required, the last element will be used for when there is no corresponding element in this array. + * @param fcMap The map containing the parsed constraints for each child component of <code>parent</code>. Will not be alterted. + * @param callbackList A list of callbacks or <code>null</code> if none. Will not be alterted. + */ + public Grid(ContainerWrapper container, LC lc, AC rowConstr, AC colConstr, Map<ComponentWrapper, CC> fcMap, ArrayList<LayoutCallback> callbackList) + { + this.lc = lc; + this.rowConstr = rowConstr; + this.colConstr = colConstr; + this.container = container; + this.callbackList = callbackList; + + int wrap = lc.getWrapAfter() != 0 ? lc.getWrapAfter() : (lc.isFlowX() ? colConstr : rowConstr).getConstaints().length; + + final ComponentWrapper[] comps = container.getComponents(); + + boolean hasTagged = false; // So we do not have to sort if it will not do any good + boolean hasPushX = false, hasPushY = false; + final int[] p = new int[2]; + final ArrayList<int[]> spannedRects = new ArrayList<int[]>(2); + + final DimConstraint[] specs = (lc.isFlowX() ? rowConstr : colConstr).getConstaints(); + + int sizeGroupsX = 0, sizeGroupsY = 0; + int[] dockInsets = null; // top, left, bottom, right insets for docks. + + LinkHandler.clearTemporaryBounds(container.getLayout()); + + for (int i = 0; i < comps.length;) { + ComponentWrapper comp = comps[i]; + CC rootCc = fcMap.get(comp); + + int hideMode = comp.isVisible() ? -1 : rootCc.getHideMode() != -1 ? rootCc.getHideMode() : lc.getHideMode(); + + if (rootCc == null || hideMode == 3) { // To work with situations where there are components that does not have a layout manager, or not this one. + if (rootCc != null) + setLinkedBounds(comp, rootCc, comp.getX(), comp.getY(), comp.getWidth(), comp.getHeight(), rootCc.isExternal()); + i++; + continue; // The "external" component should not be handled further. + } + + if (rootCc.getHorizontal().getSizeGroup() != null) + sizeGroupsX++; + if (rootCc.getVertical().getSizeGroup() != null) + sizeGroupsY++; + + // Special treatment of absolute positioned components. + UnitValue[] pos = getPos(comp, rootCc); + BoundSize[] cbSz = getCallbackSize(comp, rootCc); + if (pos != null || rootCc.isExternal()) { + + // Check if link information should be saved later. + if (pos != null) { + for (int l = 0; l < pos.length; l++) { + UnitValue u = pos[l]; + if (u != null && u.isLinkedDeep()) + addLinkTargetIDs(u); + } + } + + CompWrap cw = new CompWrap(comp, rootCc, hideMode, pos, cbSz); + Cell cell = grid.get(null); + if (cell == null) { + grid.put(null, new Cell(cw)); + } else { + cell.compWraps.add(cw); + } + + if (rootCc.isBoundsInGrid() == false || rootCc.isExternal()) { + setLinkedBounds(comp, rootCc, comp.getX(), comp.getY(), comp.getWidth(), comp.getHeight(), rootCc.isExternal()); + i++; + continue; + } + } + + if (rootCc.getDockSide() != -1) { + if (dockInsets == null) + dockInsets = new int[] {-MAX_DOCK_GRID, -MAX_DOCK_GRID, MAX_DOCK_GRID, MAX_DOCK_GRID}; + + addDockingCell(dockInsets, rootCc.getDockSide(), new CompWrap(comp, rootCc, hideMode, pos, cbSz)); + i++; + continue; + } + + Boolean cellFlowX = rootCc.getFlowX(); + Cell cell = null; + + if (rootCc.isNewline()) + wrap(p, rootCc.getNewlineGapSize(), true); + + increase(p, rootCc.getSkip()); // Probably 0 advance... + + boolean rowNoGrid = lc.isNoGrid() || ((DimConstraint) LayoutUtil.getIndexSafe(specs, lc.isFlowX() ? p[1] : p[0])).isNoGrid(); + + // Move to a free y, x if no absolute grid specified + int cx = rootCc.getCellX(); + int cy = rootCc.getCellY(); + if ((cx < 0 || cy < 0) && rowNoGrid == false) { + while (isCellFree(p[1], p[0], spannedRects) == false) { + if (Math.abs(increase(p, 1)) >= wrap) + wrap(p, null, true); + } + } else { + if (cx >= 0 && cy >= 0) { + if (cy >= 0) { + p[0] = cx; + p[1] = cy; + } else { // Only one coordinate is specified. Use the current row (flowx) or column (flowy) to fill in. + if (lc.isFlowX()) { + p[0] = cx; + } else { + p[1] = cx; + } + } + } + cell = getCell(p[1], p[0]); // Might be null + } + + // If cell is not created yet, create it and set it. + if (cell == null) { + int spanx = Math.min(rowNoGrid && lc.isFlowX() ? LayoutUtil.INF : rootCc.getSpanX(), MAX_GRID - p[0]); + int spany = Math.min(rowNoGrid && !lc.isFlowX() ? LayoutUtil.INF : rootCc.getSpanY(), MAX_GRID - p[1]); + + cell = new Cell(spanx, spany, cellFlowX != null ? cellFlowX.booleanValue() : lc.isFlowX()); + + setCell(p[1], p[0], cell); + + // Add a rectangle so we can know that spanned cells occupy more space. + if (spanx > 1 || spany > 1) + spannedRects.add(new int[] {p[0], p[1], spanx, spany}); + } + + // Add the one, or all, components that split the grid position to the same Cell. + boolean forceWrap = false; + BoundSize wrapGap = null; + int splitLeft = rowNoGrid ? LayoutUtil.INF : rootCc.getSplit() - 1; + boolean splitExit = false; + for (; splitLeft >= 0 && forceWrap == false && i < comps.length; splitLeft--) { + ComponentWrapper compAdd = comps[i]; + CC cc = fcMap.get(compAdd); // Can not be null. + + hideMode = compAdd.isVisible() ? -1 : cc.getHideMode() != -1 ? cc.getHideMode() : lc.getHideMode(); + + if (cc == null || cc.isExternal() || hideMode == 3) { + i++; + continue; // To work with situations where there are components that does not have a layout manager, or not this one. + } + + hasPushX |= (cc.getPushX() != null); + hasPushY |= (cc.getPushY() != null); + + if (cc != rootCc) { // If not first in a cell + if (cc.isNewline() || cc.isBoundsInGrid() == false) + break; + + if (splitLeft > 0 && cc.getSkip() > 0) { + splitExit = true; + break; + } + + pos = getPos(compAdd, cc); + cbSz = getCallbackSize(compAdd, cc); + } + + CompWrap cw = new CompWrap(compAdd, cc, hideMode, pos, cbSz); + cell.compWraps.add(cw); + cell.hasTagged |= cc.getTag() != null; + hasTagged |= cell.hasTagged; + + if (cc != rootCc) { + if (cc.getHorizontal().getSizeGroup() != null) + sizeGroupsX++; + if (cc.getVertical().getSizeGroup() != null) + sizeGroupsY++; + } + + int flowSpan = lc.isFlowX() ? rootCc.getSpanX() : rootCc.getSpanY(); + forceWrap = (cc.isWrap() || (flowSpan == LayoutUtil.INF && splitLeft == 0)); + wrapGap = cc.getWrapGapSize(); + i++; + } + + if (forceWrap) { + wrap(p, wrapGap, true); + } else if (rowNoGrid == false) { + int span = lc.isFlowX() ? cell.spanx : cell.spany; + if (Math.abs((lc.isFlowX() ? p[0] : p[1])) + span >= wrap) { + wrap(p, null, true); + } else { + int adv = lc.isFlowX() ? cell.spanx : cell.spany; + if (splitExit) + adv--; + increase(p, adv); + } + } + } + + // If there were size groups, calculate the largest values in the groups (for min/pref/max) and enforce them on the rest in the group. + if (sizeGroupsX > 0 || sizeGroupsY > 0) { + HashMap<String, int[]> sizeGroupMapX = sizeGroupsX > 0 ? new HashMap<String, int[]>(sizeGroupsX) : null; + HashMap<String, int[]> sizeGroupMapY = sizeGroupsY > 0 ? new HashMap<String, int[]>(sizeGroupsY) : null; + ArrayList<CompWrap> sizeGroupCWs = new ArrayList<CompWrap>(Math.max(sizeGroupsX, sizeGroupsY)); + + for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) { + Cell cell = it.next(); + for (int i = 0; i < cell.compWraps.size(); i++) { + CompWrap cw = cell.compWraps.get(i); + + if (cw.cc.getHorizontal().getSizeGroup() != null || cw.cc.getVertical().getSizeGroup() != null) { + addToSizeGroup(sizeGroupMapX, cw.cc.getHorizontal().getSizeGroup(), cw.horSizes); + addToSizeGroup(sizeGroupMapY, cw.cc.getVertical().getSizeGroup(), cw.verSizes); + sizeGroupCWs.add(cw); + } + } + } + + // Set/equalize the sizeGroups to same the values. + if (sizeGroupCWs != null) { + for (int i = 0; i < sizeGroupCWs.size(); i++) { + CompWrap cw = sizeGroupCWs.get(i); + if (sizeGroupMapX != null) + cw.setSizes(sizeGroupMapX.get(cw.cc.getHorizontal().getSizeGroup()), true); // Target method handles null sizes + if (sizeGroupMapY != null) + cw.setSizes(sizeGroupMapY.get(cw.cc.getVertical().getSizeGroup()), false); // Target method handles null sizes + } + } + } + + if (hasTagged) + sortCellsByPlatform(grid.values(), container); + + // Calculate gaps now that the cells are filled and we know all adjacent components. + boolean ltr = LayoutUtil.isLeftToRight(lc, container); + for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) { + Cell cell = it.next(); + ArrayList<CompWrap> cws = cell.compWraps; + + for (int i = 0, lastI = cws.size() - 1; i <= lastI; i++) { + CompWrap cw = cws.get(i); + ComponentWrapper cwBef = i > 0 ? cws.get(i - 1).comp : null; + ComponentWrapper cwAft = i < lastI ? cws.get(i + 1).comp : null; + + String tag = fcMap.get(cw.comp).getTag(); + CC ccBef = cwBef != null ? fcMap.get(cwBef) : null; + CC ccAft = cwAft != null ? fcMap.get(cwAft) : null; + + cw.calcGaps(cwBef, ccBef, cwAft, ccAft, tag, cell.flowx, ltr); + } + } + + dockOffX = getDockInsets(colIndexes); + dockOffY = getDockInsets(rowIndexes); + + // Add synthetic indexes for empty rows and columns so they can get a size + for (int i = 0, iSz = rowConstr.getCount(); i < iSz; i++) + rowIndexes.add(new Integer(i)); + for (int i = 0, iSz = colConstr.getCount(); i < iSz; i++) + colIndexes.add(new Integer(i)); + + colGroupLists = divideIntoLinkedGroups(false); + rowGroupLists = divideIntoLinkedGroups(true); + + growXs = getDefaultGrowWeights(hasPushX, false); + growYs = getDefaultGrowWeights(hasPushY, true); + + } + + /** If the container (parent) that this grid is laying out has changed its bounds, call this method to + * clear any cached values. + */ + public void invalidateContainerSize() + { + colFlowSpecs = null; + } + + /** Does the actual layout. Uses many values calculated in the constructor. + * @param bounds The bounds to layout against. Normally that of the parent. [x, y, width, height]. + * @param alignX The alignment for the x-axis. + * @param alignY The alignment for the y-axis. + * @param debug If debug information should be saved in {@link #debugRects}. + * @param checkPrefChange If a check should be done to see if the setting of any new bounds changes the preferred size + * of a component. This is normally only turned on for SWT as SWT has a notion of width vs height calculation. + * @return If the layout has probably change the preferred size and there is need for a new layout (normally only SWT). + */ + public boolean layout(int[] bounds, UnitValue alignX, UnitValue alignY, boolean debug, boolean checkPrefChange) + { + if (debug) + debugRects = new ArrayList<int[]>(); + + checkSizeCalcs(); + + resetLinkValues(true); + + layoutInOneDim(bounds[2], alignX, false, growXs); + layoutInOneDim(bounds[3], alignY, true, growYs); + + HashMap<String, Integer> endGrpXMap = null, endGrpYMap = null; + int compCount = container.getComponentCount(); + + // Transfer the calculated bound from the ComponentWrappers to the actual Components. + boolean layoutAgain = false; + if (compCount > 0) { + for (int j = 0; j < (linkTargetIDs != null ? 2 : 1); j++) { // First do the calculations (maybe more than once) then set the bounds when done + boolean doAgain; + int count = 0; + do { + doAgain = false; + for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) { + ArrayList<CompWrap> compWraps = it.next().compWraps; + for (int i = 0, iSz = compWraps.size(); i < iSz; i++) { + CompWrap cw = compWraps.get(i); + + if (j == 0) { + doAgain |= doAbsoluteCorrections(cw, bounds); + if (doAgain == false) { // If we are going to do this again, do not bother this time around + if (cw.cc.getHorizontal().getEndGroup() != null) + endGrpXMap = addToEndGroup(endGrpXMap, cw.cc.getHorizontal().getEndGroup(), cw.x + cw.w); + if (cw.cc.getVertical().getEndGroup() != null) + endGrpYMap = addToEndGroup(endGrpYMap, cw.cc.getVertical().getEndGroup(), cw.y + cw.h); + } + } + + if (linkTargetIDs == null || j == 1) { + if (cw.cc.getHorizontal().getEndGroup() != null) + cw.w = endGrpXMap.get(cw.cc.getHorizontal().getEndGroup()).intValue() - cw.x; + if (cw.cc.getVertical().getEndGroup() != null) + cw.h = endGrpYMap.get(cw.cc.getVertical().getEndGroup()).intValue() - cw.y; + + cw.x += bounds[0]; + cw.y += bounds[1]; + layoutAgain = cw.transferBounds(checkPrefChange && !layoutAgain); + + if (callbackList != null) { + for (int cb = 0; cb < callbackList.size(); cb++) + callbackList.get(cb).correctBounds(cw.comp); + } + } + } + } + clearGroupLinkBounds(); + if (++count > ((compCount << 3) + 10)) { + System.err.println("Unstable Cyclic Dependency in absolute-linked values!"); + break; + } + + } while (doAgain); + } + } + + // Add debug shapes for the "cells". Use the CompWraps as base for inding the cells. + if (debug) { + Collection<Cell> cwColl = grid.values(); + for (Iterator<Cell> it = cwColl.iterator(); it.hasNext();) { + ArrayList<CompWrap> compWraps = it.next().compWraps; + for (int i = 0, iSz = compWraps.size(); i < iSz; i++) { + CompWrap cw = compWraps.get(i); + LinkedDimGroup hGrp = getGroupContaining(colGroupLists, cw); + LinkedDimGroup vGrp = getGroupContaining(rowGroupLists, cw); + + if (hGrp != null && vGrp != null) + debugRects.add(new int[] {hGrp.lStart + bounds[0] - (hGrp.fromEnd ? hGrp.lSize : 0), vGrp.lStart + bounds[1] - (vGrp.fromEnd ? vGrp.lSize : 0), hGrp.lSize, vGrp.lSize}); + } + } + } + return layoutAgain; + } + + public void paintDebug() + { + if (debugRects != null) { + container.paintDebugOutline(); + + ArrayList<int[]> painted = new ArrayList<int[]>(); + for (int i = 0, iSz = debugRects.size(); i < iSz; i++) { + int[] r = debugRects.get(i); + if (painted.contains(r) == false) { + container.paintDebugCell(r[0], r[1], r[2], r[3]); + painted.add(r); + } + } + + for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) { + ArrayList<CompWrap> compWraps = it.next().compWraps; + for (int i = 0, iSz = compWraps.size(); i < iSz; i++) + compWraps.get(i).comp.paintDebugOutline(); + } + } + } + + public final int[] getWidth() + { + checkSizeCalcs(); + return width; + } + + public final int[] getHeight() + { + checkSizeCalcs(); + return height; + } + + private void checkSizeCalcs() + { + if (colFlowSpecs == null) { + colFlowSpecs = calcRowsOrColsSizes(colGroupLists, growXs, container.getWidth(), true); + rowFlowSpecs = calcRowsOrColsSizes(rowGroupLists, growYs, container.getHeight(), false); + + width = getMinPrefMaxSumSize(colFlowSpecs.sizes); + height = getMinPrefMaxSumSize(rowFlowSpecs.sizes); + + resetLinkValues(false); + + adjustSizeForAbsolute(width, true); + adjustSizeForAbsolute(height, false); + } + } + + private final UnitValue[] getPos(ComponentWrapper cw, CC cc) + { + UnitValue[] cbPos = null; + if (callbackList != null) { + for (int i = 0; i < callbackList.size() && cbPos == null; i++) + cbPos = callbackList.get(i).getPosition(cw); // NOT a copy! + } + + // If one is null, return the other (which many also be null) + UnitValue[] ccPos = cc.getPos(); // A copy!! + if (cbPos == null || ccPos == null) + return cbPos != null ? cbPos : ccPos; + + // Merge + for (int i = 0; i < 4; i++) { + UnitValue cbUv = cbPos[i]; + if (cbUv != null) + ccPos[i] = cbUv; + } + + return ccPos; + } + private final BoundSize[] getCallbackSize(ComponentWrapper cw, CC cc) + { + if (callbackList != null) { + for (int i = 0; i < callbackList.size(); i++) { + BoundSize[] bs = callbackList.get(i).getSize(cw); // NOT a copy! + if (bs != null) + return bs; + } + } + return null; + } + + private final int getDockInsets(TreeSet<Integer> set) + { + int c = 0; + for (Iterator<Integer> it = set.iterator(); it.hasNext();) { + if (it.next().intValue() < -MAX_GRID) { + c++; + } else { + break; // Since they are sorted we can break + } + } + return c; + } + + /** + * @param cw Never <code>null</code>. + * @param fc Never <code>null</code>. + * @param external The bounds should be stored even if they are not in {@link #linkTargetIDs}. + * @return IF a change has been done. + */ + private boolean setLinkedBounds(ComponentWrapper cw, CC fc, int x, int y, int w, int h, boolean external) + { + String id = fc.getId() != null ? fc.getId() : cw.getLinkId(); + if (id == null) + return false; + + String gid = null; + int grIx = id.indexOf('.'); + if (grIx != -1 ) { + gid = id.substring(0, grIx); + id = id.substring(grIx + 1); + } + + Object lay = container.getLayout(); + boolean changed = false; + if (external || (linkTargetIDs != null && linkTargetIDs.containsKey(id))) + changed = LinkHandler.setBounds(lay, id, x, y, w, h, !external, false); + + if (gid != null && (external || (linkTargetIDs != null && linkTargetIDs.containsKey(gid)))) { + if (linkTargetIDs == null) + linkTargetIDs = new HashMap<String, Boolean>(4); + + linkTargetIDs.put(gid, Boolean.TRUE); + changed |= LinkHandler.setBounds(lay, gid, x, y, w, h, !external, true); + } + + return changed; + } + + private void addLinkTargetIDs(UnitValue uv) + { + if (uv.isLinked()) { + if (linkTargetIDs == null) + linkTargetIDs = new HashMap<String, Boolean>(4); + + linkTargetIDs.put(uv.getLinkTargetId(), null); + } else { + for (int i = uv.getSubUnitCount() - 1; i >= 0; i--) { + UnitValue subUv = uv.getSubUnitValue(i); + if (subUv.isLinkedDeep()) + addLinkTargetIDs(subUv); + } + } + } + + /** Go to next cell. + * @param p The point to increase + * @param cnt How many cells to advance. + * @return The new value in the "incresing" dimension. + */ + private final int increase(int[] p, int cnt) + { + return lc.isFlowX() ? (p[0] += cnt) : (p[1] += cnt); + } + + /** Wraps to the next row or column depending on if horizontal flow or vertical flow is used. + * @param p The point to wrap and thus set either x or y to 0 and increase the other one. + * @param gapSize The gaps size specified in a "wrap XXX" or "newline XXX" or <code>null</code> if none. + * @param isWrap If gapSize is from a "wrap" (true) or "newline" (false). + */ + private final void wrap(int[] p, BoundSize gapSize, boolean isWrap) + { + boolean flowx = lc.isFlowX(); + p[0] = flowx ? 0 : p[0] + 1; + p[1] = flowx ? p[1] + 1 : 0; + + if (gapSize != null) { + if (wrapGapMap == null) + wrapGapMap = new HashMap<Integer, BoundSize>(8); + int ix = p[flowx ? 1 : 0]; + if (isWrap == false) + ix--; // newline. Use index before increment. + wrapGapMap.put(new Integer(ix), gapSize); + + // add the row/column so that the gap in the last row/col will not be removed. + if (flowx) { + rowIndexes.add(new Integer(p[1])); + } else { + colIndexes.add(new Integer(p[0])); + } + } + } + + /** Sort components (normally buttons in a button bar) so they appear in the correct order. + * @param cells The cells to sort. + * @param parent The parent. + */ + private static void sortCellsByPlatform(Collection<Cell> cells, ContainerWrapper parent) + { + String order = PlatformDefaults.getButtonOrder(); + String orderLo = order.toLowerCase(); + + int unrelSize = PlatformDefaults.convertToPixels(1, "u", true, 0, parent, null); + + if (unrelSize == UnitConverter.UNABLE) + throw new IllegalArgumentException("'unrelated' not recognized by PlatformDefaults!"); + + int[] gapUnrel = new int[] {unrelSize, unrelSize, LayoutUtil.NOT_SET}; + int[] flGap = new int[] {0, 0, LayoutUtil.NOT_SET}; + + for (Iterator<Cell> it = cells.iterator(); it.hasNext();) { + Cell cell = it.next(); + if (cell.hasTagged == false) + continue; + + CompWrap prevCW = null; + boolean nextUnrel = false; + boolean nextPush = false; + ArrayList<CompWrap> sortedList = new ArrayList<CompWrap>(cell.compWraps.size()); + + for (int i = 0, iSz = orderLo.length(); i < iSz; i++) { + char c = orderLo.charAt(i); + if (c == '+' || c == '_') { + nextUnrel = true; + if (c == '+') + nextPush = true; + } else { + String tag = PlatformDefaults.getTagForChar(c); + if (tag != null) { + for (int j = 0, jSz = cell.compWraps.size(); j < jSz; j++) { + CompWrap cw = cell.compWraps.get(j); + if (tag.equals(cw.cc.getTag())) { + if (Character.isUpperCase(order.charAt(i))) { + int min = PlatformDefaults.getMinimumButtonWidth().getPixels(0, parent, cw.comp); + if (min > cw.horSizes[LayoutUtil.MIN]) + cw.horSizes[LayoutUtil.MIN] = min; + + correctMinMax(cw.horSizes); + } + + sortedList.add(cw); + + if (nextUnrel) { + (prevCW != null ? prevCW : cw).mergeGapSizes(gapUnrel, cell.flowx, prevCW == null); + if (nextPush) { + cw.forcedPushGaps = 1; + nextUnrel = false; + nextPush = false; + } + } + + // "unknown" components will always get an Unrelated gap. + if (c == 'u') + nextUnrel = true; + prevCW = cw; + } + } + } + } + } + + // If we have a gap that was supposed to push but no more components was found to but the "gap before" then compensate. + if (sortedList.size() > 0) { + CompWrap cw = sortedList.get(sortedList.size() - 1); + if (nextUnrel) { + cw.mergeGapSizes(gapUnrel, cell.flowx, false); + if (nextPush) + cw.forcedPushGaps |= 2; + } + + // Remove first and last gap if not set explicitly. + if (cw.cc.getHorizontal().getGapAfter() == null) + cw.setGaps(flGap, 3); + + cw = sortedList.get(0); + if (cw.cc.getHorizontal().getGapBefore() == null) + cw.setGaps(flGap, 1); + } + + // Exchange the unsorted CompWraps for the sorted one. + if (cell.compWraps.size() == sortedList.size()) { + cell.compWraps.clear(); + } else { + cell.compWraps.removeAll(sortedList); + } + cell.compWraps.addAll(sortedList); + } + } + + private Float[] getDefaultGrowWeights(boolean hasPush, boolean isRows) + { + if (hasPush == false && (isRows ? lc.isFillY() : lc.isFillX()) == false) + return null; + + ArrayList<LinkedDimGroup>[] groupLists = isRows ? rowGroupLists : colGroupLists; + + Float[] gwArr = GROW_100; // Only create specific if any of the components have grow. + for (int i = 0, ix = 1; i < groupLists.length; i++, ix += 2) { + ArrayList<LinkedDimGroup> grps = groupLists[i]; + Float rowGw = null; + for (int j = 0; j < grps.size(); j++) { + LinkedDimGroup grp = grps.get(j); + + for (int c = 0; c < grp._compWraps.size(); c++) { + CompWrap cw = grp._compWraps.get(c); + Float gw = hasPush ? (isRows ? cw.cc.getPushY() : cw.cc.getPushX()) : (isRows ? cw.cc.getVertical() : cw.cc.getHorizontal()).getGrow(); + if (rowGw == null || (gw != null && gw.floatValue() > rowGw.floatValue())) + rowGw = gw; + } + } + + if (rowGw != null) { + if (gwArr == GROW_100) + gwArr = new Float[(groupLists.length << 1) + 1]; + gwArr[ix] = rowGw; + } + } + + return gwArr; + } + + private void clearGroupLinkBounds() + { + if (linkTargetIDs == null) + return; + + for (Iterator<Map.Entry<String,Boolean>> it = linkTargetIDs.entrySet().iterator(); it.hasNext();) { + Map.Entry<String, Boolean> o = it.next(); + if (o.getValue() == Boolean.TRUE) + LinkHandler.clearBounds(container.getLayout(), o.getKey()); + } + } + + private void resetLinkValues(boolean parentSize) + { + Object lay = container.getLayout(); + LinkHandler.clearTemporaryBounds(lay); + + boolean defIns = !hasDocks(); + + int parW = parentSize ? container.getWidth() : 0; + int parH = parentSize ? container.getHeight() : 0; + int insX = LayoutUtil.getInsets(lc, 0, defIns).getPixels(0, container, null); + int insY = LayoutUtil.getInsets(lc, 1, defIns).getPixels(0, container, null); + int insW = parW - insX - LayoutUtil.getInsets(lc, 2, defIns).getPixels(0, container, null); + int insH = parH - insY - LayoutUtil.getInsets(lc, 3, defIns).getPixels(0, container, null); + + LinkHandler.setBounds(lay, "visual", insX, insY, insW, insH, true, false); + LinkHandler.setBounds(lay, "container", 0, 0, parW, parH, true, false); + } + + /** Returns the {@link net.miginfocom.layout.Grid.LinkedDimGroup} that has the {@link net.miginfocom.layout.Grid.CompWrap} + * <code>cw</code>. + * @param groupLists The lists to search in. + * @param cw The component wrap to find. + * @return The linked group or <code>null</code> if none had the component wrap. + */ + private static LinkedDimGroup getGroupContaining(ArrayList<LinkedDimGroup>[] groupLists, CompWrap cw) + { + for (int i = 0; i < groupLists.length; i++) { + ArrayList<LinkedDimGroup> groups = groupLists[i]; + for (int j = 0, jSz = groups.size(); j < jSz; j++) { + ArrayList<CompWrap> cwList = groups.get(j)._compWraps; + for (int k = 0, kSz = cwList.size(); k < kSz; k++) { + if (cwList.get(k) == cw) + return groups.get(j); + } + } + } + return null; + } + + private boolean doAbsoluteCorrections(CompWrap cw, int[] bounds) + { + boolean changed = false; + + int[] stSz = getAbsoluteDimBounds(cw, bounds[2], true); + if (stSz != null) + cw.setDimBounds(stSz[0], stSz[1], true); + + stSz = getAbsoluteDimBounds(cw, bounds[3], false); + if (stSz != null) + cw.setDimBounds(stSz[0], stSz[1], false); + + // If there is a link id, store the new bounds. + if (linkTargetIDs != null) + changed = setLinkedBounds(cw.comp, cw.cc, cw.x, cw.y, cw.w, cw.h, false); + + return changed; + } + + private void adjustSizeForAbsolute(int[] curSizes, boolean isHor) + { + Cell absCell = grid.get(null); + if (absCell == null || absCell.compWraps.size() == 0) + return; + + ArrayList<CompWrap> cws = absCell.compWraps; + + int maxEnd = 0; + for (int j = 0, cwSz = absCell.compWraps.size(); j < cwSz + 3; j++) { // "Do Again" max absCell.compWraps.size() + 3 times. + boolean doAgain = false; + for (int i = 0; i < cwSz; i++) { + CompWrap cw = cws.get(i); + int[] stSz = getAbsoluteDimBounds(cw, 0, isHor); + int end = stSz[0] + stSz[1]; + if (maxEnd < end) + maxEnd = end; + + // If there is a link id, store the new bounds. + if (linkTargetIDs != null) + doAgain |= setLinkedBounds(cw.comp, cw.cc, stSz[0], stSz[0], stSz[1], stSz[1], false); + } + if (doAgain == false) + break; + + // We need to check this again since the coords may be smaller this round. + maxEnd = 0; + clearGroupLinkBounds(); + } + + maxEnd += LayoutUtil.getInsets(lc, isHor ? 3 : 2, !hasDocks()).getPixels(0, container, null); + + if (curSizes[LayoutUtil.MIN] < maxEnd) + curSizes[LayoutUtil.MIN] = maxEnd; + if (curSizes[LayoutUtil.PREF] < maxEnd) + curSizes[LayoutUtil.PREF] = maxEnd; + } + + private int[] getAbsoluteDimBounds(CompWrap cw, int refSize, boolean isHor) + { + if (cw.cc.isExternal()) { + if (isHor) { + return new int[] {cw.comp.getX(), cw.comp.getWidth()}; + } else { + return new int[] {cw.comp.getY(), cw.comp.getHeight()}; + } + } + + int[] plafPad = lc.isVisualPadding() ? cw.comp.getVisualPadding() : null; + UnitValue[] pad = cw.cc.getPadding(); + + // If no changes do not create a lot of objects + if (cw.pos == null && plafPad == null && pad == null) + return null; + + // Set start + int st = isHor ? cw.x : cw.y; + int sz = isHor ? cw.w : cw.h; + + // If absolute, use those coordinates instead. + if (cw.pos != null) { + UnitValue stUV = cw.pos != null ? cw.pos[isHor ? 0 : 1] : null; + UnitValue endUV = cw.pos != null ? cw.pos[isHor ? 2 : 3] : null; + + int minSz = cw.getSize(LayoutUtil.MIN, isHor); + int maxSz = cw.getSize(LayoutUtil.MAX, isHor); + sz = Math.min(Math.max(cw.getSize(LayoutUtil.PREF, isHor), minSz), maxSz); + + if (stUV != null) { + st = stUV.getPixels(stUV.getUnit() == UnitValue.ALIGN ? sz : refSize, container, cw.comp); + + if (endUV != null) // if (endUV == null && cw.cc.isBoundsIsGrid() == true) + sz = Math.min(Math.max((isHor ? (cw.x + cw.w) : (cw.y + cw.h)) - st, minSz), maxSz); + } + + if (endUV != null) { + if (stUV != null) { // if (stUV != null || cw.cc.isBoundsIsGrid()) { + sz = Math.min(Math.max(endUV.getPixels(refSize, container, cw.comp) - st, minSz), maxSz); + } else { + st = endUV.getPixels(refSize, container, cw.comp) - sz; + } + } + } + + // If constraint has padding -> correct the start/size + if (pad != null) { + UnitValue uv = pad[isHor ? 1 : 0]; + int p = uv != null ? uv.getPixels(refSize, container, cw.comp) : 0; + st += p; + uv = pad[isHor ? 3 : 2]; + sz += -p + (uv != null ? uv.getPixels(refSize, container, cw.comp) : 0); + } + + // If the plaf converter has padding -> correct the start/size + if (plafPad != null) { + int p = plafPad[isHor ? 1 : 0]; + st += p; + sz += -p + (plafPad[isHor ? 3 : 2]); + } + + return new int[] {st, sz}; + } + + private void layoutInOneDim(int refSize, UnitValue align, boolean isRows, Float[] defaultGrowW) + { + boolean fromEnd = !(isRows ? lc.isTopToBottom() : LayoutUtil.isLeftToRight(lc, container)); + DimConstraint[] primDCs = (isRows ? rowConstr : colConstr).getConstaints(); + FlowSizeSpec fss = isRows ? rowFlowSpecs : colFlowSpecs; + ArrayList<LinkedDimGroup>[] rowCols = isRows ? rowGroupLists : colGroupLists; + + int[] rowColSizes = LayoutUtil.calculateSerial(fss.sizes, fss.resConstsInclGaps, defaultGrowW, LayoutUtil.PREF, refSize); + + if (LayoutUtil.isDesignTime(container)) { + TreeSet<Integer> indexes = isRows ? rowIndexes : colIndexes; + int[] ixArr = new int[indexes.size()]; + int ix = 0; + for (Integer i : indexes) + ixArr[ix++] = i.intValue(); + + putSizesAndIndexes(container.getComponent(), rowColSizes, ixArr, isRows); + } + + int curPos = align != null ? Math.round(align.getPixels(refSize - LayoutUtil.sum(rowColSizes), container, null)) : 0; + + if (fromEnd) + curPos = refSize - curPos; + + for (int i = 0 ; i < rowCols.length; i++) { + ArrayList<LinkedDimGroup> linkedGroups = rowCols[i]; + int scIx = i - (isRows ? dockOffY : dockOffX); + + int bIx = i << 1; + int bIx2 = bIx + 1; + + curPos += (fromEnd ? -rowColSizes[bIx] : rowColSizes[bIx]); + + DimConstraint primDC = scIx >= 0 ? primDCs[scIx >= primDCs.length ? primDCs.length - 1 : scIx] : DOCK_DIM_CONSTRAINT; + + int rowSize = rowColSizes[bIx2]; + + for (int j = 0; j < linkedGroups.size(); j++) { + LinkedDimGroup group = linkedGroups.get(j); + int groupSize = rowSize; + if (group.span > 1) + groupSize = LayoutUtil.sum(rowColSizes, bIx2, Math.min((group.span << 1) - 1, rowColSizes.length - bIx2 - 1)); + + group.layout(primDC, curPos, groupSize, group.span); + } + + curPos += (fromEnd ? -rowSize : rowSize); + } + } + + private void addToSizeGroup(HashMap<String, int[]> sizeGroups, String sizeGroup, int[] size) + { + if (sizeGroups == null) + return; + + int[] sgSize = sizeGroups.get(sizeGroup); + if (sgSize == null) { + sizeGroups.put(sizeGroup, new int[] {size[LayoutUtil.MIN], size[LayoutUtil.PREF], size[LayoutUtil.MAX]}); + } else { + sgSize[LayoutUtil.MIN] = Math.max(size[LayoutUtil.MIN], sgSize[LayoutUtil.MIN]); + sgSize[LayoutUtil.PREF] = Math.max(size[LayoutUtil.PREF], sgSize[LayoutUtil.PREF]); + sgSize[LayoutUtil.MAX] = Math.min(size[LayoutUtil.MAX], sgSize[LayoutUtil.MAX]); + } + } + + private HashMap<String, Integer> addToEndGroup(HashMap<String, Integer> endGroups, String endGroup, int end) + { + if (endGroup != null) { + if (endGroups == null) + endGroups = new HashMap<String, Integer>(2); + + Integer oldEnd = endGroups.get(endGroup); + if (oldEnd == null || end > oldEnd.intValue()) + endGroups.put(endGroup, new Integer(end)); + } + return endGroups; + } + + /** Calculates Min, Preferred and Max size for the columns OR rows. + * @param defGrow The default grow weight if the specs does not have anyone that will grow. Comes from "push" in the CC. + * @return The sizes in a {@link net.miginfocom.layout.Grid.FlowSizeSpec}. + */ + private FlowSizeSpec calcRowsOrColsSizes(ArrayList<LinkedDimGroup>[] groupsLists, Float[] defGrow, int refSize, boolean isHor) + { + DimConstraint[] primDCs = (isHor? colConstr : rowConstr).getConstaints(); + TreeSet<Integer> primIdexes = isHor ? colIndexes : rowIndexes; + + int[][] rowColBoundSizes = new int[primIdexes.size()][]; + HashMap<String, int[]> sizeGroupMap = new HashMap<String, int[]>(2); + DimConstraint[] allDCs = new DimConstraint[primIdexes.size()]; + + Iterator<Integer> primIt = primIdexes.iterator(); + for (int r = 0; r < rowColBoundSizes.length; r++) { + int cellIx = primIt.next().intValue(); + int[] rowColSizes = new int[3]; + + if (cellIx >= -MAX_GRID && cellIx <= MAX_GRID) { // If not dock cell + allDCs[r] = primDCs[cellIx >= primDCs.length ? primDCs.length - 1 : cellIx]; + } else { + allDCs[r] = DOCK_DIM_CONSTRAINT; + } + + ArrayList<LinkedDimGroup> groups = groupsLists[r]; + + int[] groupSizes = new int[] { + getTotalGroupsSizeParallel(groups, LayoutUtil.MIN, false), + getTotalGroupsSizeParallel(groups, LayoutUtil.PREF, false), + LayoutUtil.INF}; + + correctMinMax(groupSizes); + BoundSize dimSize = allDCs[r].getSize(); + + for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.MAX; sType++) { + + int rowColSize = groupSizes[sType]; + + UnitValue uv = dimSize != null ? dimSize.getSize(sType) : null; + if (uv != null) { + // If the size of the column is a link to some other size, use that instead + int unit = uv.getUnit(); + if (unit == UnitValue.PREF_SIZE) { + rowColSize = groupSizes[LayoutUtil.PREF]; + } else if (unit == UnitValue.MIN_SIZE) { + rowColSize = groupSizes[LayoutUtil.MIN]; + } else if (unit == UnitValue.MAX_SIZE) { + rowColSize = groupSizes[LayoutUtil.MAX]; + } else { + rowColSize = uv.getPixels(refSize, container, null); + } + } else if (cellIx >= -MAX_GRID && cellIx <= MAX_GRID && rowColSize == 0) { + rowColSize = LayoutUtil.isDesignTime(container) ? LayoutUtil.getDesignTimeEmptySize() : 0; // Empty rows with no size set gets XX pixels if design time + } + + rowColSizes[sType] = rowColSize; + } + + correctMinMax(rowColSizes); + addToSizeGroup(sizeGroupMap, allDCs[r].getSizeGroup(), rowColSizes); + + rowColBoundSizes[r] = rowColSizes; + } + + // Set/equalize the size groups to same the values. + if (sizeGroupMap.size() > 0) { + for (int r = 0; r < rowColBoundSizes.length; r++) { + if (allDCs[r].getSizeGroup() != null) + rowColBoundSizes[r] = sizeGroupMap.get(allDCs[r].getSizeGroup()); + } + } + + // Add the gaps + ResizeConstraint[] resConstrs = getRowResizeConstraints(allDCs); + + boolean[] fillInPushGaps = new boolean[allDCs.length + 1]; + int[][] gapSizes = getRowGaps(allDCs, refSize, isHor, fillInPushGaps); + + + FlowSizeSpec fss = mergeSizesGapsAndResConstrs(resConstrs, fillInPushGaps, rowColBoundSizes, gapSizes, refSize, container); + + // Spanning components are not handled yet. Check and adjust the multi-row min/pref they enforce. + adjustMinPrefForSpanningComps(allDCs, defGrow, fss, groupsLists); + + return fss; + } + + private static int[] getMinPrefMaxSumSize(int[][] sizes) + { + int[] retSizes = new int[3]; + + for (int i = 0; i < sizes.length; i++) { + if (sizes[i] != null) { + int[] size = sizes[i]; + for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.MAX; sType++) { + int s = size[sType]; + + if (s != LayoutUtil.NOT_SET) { + if (sType == LayoutUtil.PREF) { + int bnd = size[LayoutUtil.MAX]; + if (bnd != LayoutUtil.NOT_SET && bnd < s) + s = bnd; + + bnd = size[LayoutUtil.MIN]; + if (bnd > s) // Includes s == LayoutUtil.NOT_SET since < 0. + s = bnd; + } + + retSizes[sType] += s; // MAX compensated below. + } + } + + // So that MAX is always correct. + if (size[LayoutUtil.MAX] == LayoutUtil.NOT_SET) + retSizes[LayoutUtil.MAX] = LayoutUtil.INF; + } + } + + return retSizes; + } + + private static ResizeConstraint[] getRowResizeConstraints(DimConstraint[] specs) + { + ResizeConstraint[] resConsts = new ResizeConstraint[specs.length]; + for (int i = 0; i < resConsts.length; i++) + resConsts[i] = specs[i].resize; + return resConsts; + } + + private static ResizeConstraint[] getComponentResizeConstraints(ArrayList<CompWrap> compWraps, boolean isHor) + { + ResizeConstraint[] resConsts = new ResizeConstraint[compWraps.size()]; + for (int i = 0; i < resConsts.length; i++) { + CC fc = compWraps.get(i).cc; + resConsts[i] = fc.getDimConstraint(isHor).resize; + + // Always grow docking components in the correct dimension. + int dock = fc.getDockSide(); + if (isHor ? (dock == 0 || dock == 2) : (dock == 1 || dock == 3)) { + ResizeConstraint dc = resConsts[i]; + resConsts[i] = new ResizeConstraint(dc.shrinkPrio, dc.shrink, dc.growPrio, ResizeConstraint.WEIGHT_100); + } + } + return resConsts; + } + + private static boolean[] getComponentGapPush(ArrayList<CompWrap> compWraps, boolean isHor) + { + // Make one element bigger and or the after gap with the next before gap. + boolean[] barr = new boolean[compWraps.size() + 1]; + for (int i = 0; i < barr.length; i++) { + + boolean push = i > 0 ? compWraps.get(i - 1).isPushGap(isHor, false) : false; + + if (push == false && i < (barr.length - 1)) + push = compWraps.get(i).isPushGap(isHor, true); + + barr[i] = push; + } + return barr; + } + + /** Returns the row gaps in pixel sizes. One more than there are <code>specs</code> sent in. + * @param specs + * @param refSize + * @param isHor + * @param fillInPushGaps If the gaps are pushing. <b>NOTE!</b> this argument will be filled in and thus changed! + * @return The row gaps in pixel sizes. One more than there are <code>specs</code> sent in. + */ + private int[][] getRowGaps(DimConstraint[] specs, int refSize, boolean isHor, boolean[] fillInPushGaps) + { + BoundSize defGap = isHor ? lc.getGridGapX() : lc.getGridGapY(); + if (defGap == null) + defGap = isHor ? PlatformDefaults.getGridGapX() : PlatformDefaults.getGridGapY(); + int[] defGapArr = defGap.getPixelSizes(refSize, container, null); + + boolean defIns = !hasDocks(); + + UnitValue firstGap = LayoutUtil.getInsets(lc, isHor ? 1 : 0, defIns); + UnitValue lastGap = LayoutUtil.getInsets(lc, isHor ? 3 : 2, defIns); + + int[][] retValues = new int[specs.length + 1][]; + + for (int i = 0, wgIx = 0; i < retValues.length; i++) { + DimConstraint specBefore = i > 0 ? specs[i - 1] : null; + DimConstraint specAfter = i < specs.length ? specs[i] : null; + + // No gap if between docking components. + boolean edgeBefore = (specBefore == DOCK_DIM_CONSTRAINT || specBefore == null); + boolean edgeAfter = (specAfter == DOCK_DIM_CONSTRAINT || specAfter == null); + if (edgeBefore && edgeAfter) + continue; + + BoundSize wrapGapSize = (wrapGapMap == null || isHor == lc.isFlowX() ? null : wrapGapMap.get(new Integer(wgIx++))); + + if (wrapGapSize == null) { + + int[] gapBefore = specBefore != null ? specBefore.getRowGaps(container, null, refSize, false) : null; + int[] gapAfter = specAfter != null ? specAfter.getRowGaps(container, null, refSize, true) : null; + + if (edgeBefore && gapAfter == null && firstGap != null) { + + int bef = firstGap.getPixels(refSize, container, null); + retValues[i] = new int[] {bef, bef, bef}; + + } else if (edgeAfter && gapBefore == null && firstGap != null) { + + int aft = lastGap.getPixels(refSize, container, null); + retValues[i] = new int[] {aft, aft, aft}; + + } else { + retValues[i] = gapAfter != gapBefore ? mergeSizes(gapAfter, gapBefore) : new int[] {defGapArr[0], defGapArr[1], defGapArr[2]}; + } + + if (specBefore != null && specBefore.isGapAfterPush() || specAfter != null && specAfter.isGapBeforePush()) + fillInPushGaps[i] = true; + } else { + + if (wrapGapSize.isUnset()) { + retValues[i] = new int[] {defGapArr[0], defGapArr[1], defGapArr[2]}; + } else { + retValues[i] = wrapGapSize.getPixelSizes(refSize, container, null); + } + fillInPushGaps[i] = wrapGapSize.getGapPush(); + } + } + return retValues; + } + + private static int[][] getGaps(ArrayList<CompWrap> compWraps, boolean isHor) + { + int compCount = compWraps.size(); + int[][] retValues = new int[compCount + 1][]; + + retValues[0] = compWraps.get(0).getGaps(isHor, true); + for (int i = 0; i < compCount; i++) { + int[] gap1 = compWraps.get(i).getGaps(isHor, false); + int[] gap2 = i < compCount - 1 ? compWraps.get(i + 1).getGaps(isHor, true) : null; + + retValues[i + 1] = mergeSizes(gap1, gap2); + } + + return retValues; + } + + private boolean hasDocks() + { + return (dockOffX > 0 || dockOffY > 0 || rowIndexes.last() > MAX_GRID || colIndexes.last() > MAX_GRID); + } + + /** + * @param specs The specs for the columns or rows. Last index will be used of <code>count</code> is greater than this array's length. + * @param defGrow The default grow weight if the specs does not have anyone that will grow. Comes from "push" in the CC. + * @param fss + * @param groupsLists + */ + private void adjustMinPrefForSpanningComps(DimConstraint[] specs, Float[] defGrow, FlowSizeSpec fss, ArrayList<LinkedDimGroup>[] groupsLists) + { + for (int r = 0; r < groupsLists.length; r++) { + ArrayList<LinkedDimGroup> groups = groupsLists[r]; + + for (int i = 0; i < groups.size(); i++) { + LinkedDimGroup group = groups.get(i); + if (group.span == 1) + continue; + + int cSize = group.getMinPrefMax()[LayoutUtil.PREF]; + if (cSize == LayoutUtil.NOT_SET) + continue; + + int rowSize = 0; + int sIx = (r << 1) + 1; + int len = Math.min((group.span << 1), fss.sizes.length - sIx) - 1; + for (int j = sIx; j < sIx + len; j++) { + int sz = fss.sizes[j][LayoutUtil.PREF]; + if (sz != LayoutUtil.NOT_SET) + rowSize += sz; + } + + if (rowSize < cSize) { + for (int eag = 0, newRowSize = 0; eag < 4 && newRowSize < cSize; eag++) + newRowSize = fss.expandSizes(specs, defGrow, cSize, sIx, len, LayoutUtil.PREF, eag); + } + } + } + } + + /** For one dimension divide the component wraps into logical groups. One group for component wraps that share a common something, + * line the property to layout by base line. + * @param isRows If rows, and not columns, are to be divided. + * @return One <code>ArrayList<LinkedDimGroup></code> for every row/column. + */ + private ArrayList<LinkedDimGroup>[] divideIntoLinkedGroups(boolean isRows) + { + boolean fromEnd = !(isRows ? lc.isTopToBottom() : LayoutUtil.isLeftToRight(lc, container)); + TreeSet<Integer> primIndexes = isRows ? rowIndexes : colIndexes; + TreeSet<Integer> secIndexes = isRows ? colIndexes : rowIndexes; + DimConstraint[] primDCs = (isRows ? rowConstr : colConstr).getConstaints(); + + ArrayList<LinkedDimGroup>[] groupLists = new ArrayList[primIndexes.size()]; + + int gIx = 0; + for (Iterator<Integer> primIt = primIndexes.iterator(); primIt.hasNext();) { + int i = primIt.next().intValue(); + + DimConstraint dc; + if (i >= -MAX_GRID && i <= MAX_GRID) { // If not dock cell + dc = primDCs[i >= primDCs.length ? primDCs.length - 1 : i]; + } else { + dc = DOCK_DIM_CONSTRAINT; + } + + ArrayList<LinkedDimGroup> groupList = new ArrayList<LinkedDimGroup>(2); + groupLists[gIx++] = groupList; + + for (Iterator<Integer> secIt = secIndexes.iterator(); secIt.hasNext();) { + int j = secIt.next().intValue(); + Cell cell = isRows ? getCell(i, j) : getCell(j, i); + if (cell == null || cell.compWraps.size() == 0) + continue; + + int span = (isRows ? cell.spany : cell.spanx); + if (span > 1) + span = convertSpanToSparseGrid(i, span, primIndexes); + + boolean isPar = cell.flowx == isRows; + + if ((isPar == false && cell.compWraps.size() > 1) || span > 1) { + + int linkType = isPar ? LinkedDimGroup.TYPE_PARALLEL : LinkedDimGroup.TYPE_SERIAL; + LinkedDimGroup lg = new LinkedDimGroup("p," + j, span, linkType, !isRows, fromEnd); + lg.setCompWraps(cell.compWraps); + groupList.add(lg); + } else { + for (int cwIx = 0; cwIx < cell.compWraps.size(); cwIx++) { + CompWrap cw = cell.compWraps.get(cwIx); + boolean rowBaselineAlign = (isRows && dc.getAlignOrDefault(!isRows) == UnitValue.BASELINE_IDENTITY); + + String linkCtx = cw.getLinkContext(rowBaselineAlign); + + // Find a group with same link context and put it in that group. + boolean foundList = false; + for (int glIx = 0, lastGl = groupList.size() - 1; glIx <= lastGl ; glIx++) { + LinkedDimGroup group = groupList.get(glIx); + if (group.linkCtx == linkCtx || linkCtx != null && linkCtx.equals(group.linkCtx)) { + group.addCompWrap(cw); + foundList = true; + break; + } + } + + // If none found and at last add a new group. + if (foundList == false) { + + int linkType = LinkedDimGroup.TYPE_PARALLEL; + if (isRows && cw.isBaselineAlign(rowBaselineAlign)) + linkType = LinkedDimGroup.TYPE_BASELINE; + + LinkedDimGroup lg = new LinkedDimGroup(linkCtx, 1, linkType, !isRows, fromEnd); + lg.addCompWrap(cw); + groupList.add(lg); + } + } + } + } + } + return groupLists; + } + + /** Spanning is specified in the uncompressed grid number. They can for instance be more than 60000 for the outer + * edge dock grid cells. When the grid is compressed and indexed after only the cells that area occupied the span + * is erratic. This method use the row/col indexes and corrects the span to be correct for the compressed grid. + * @param span The span un the uncompressed grid. <code>LayoutUtil.INF</code> will be interpreted to span the rest + * of the column/row excluding the surrounding docking components. + * @param indexes The indexes in the correct dimension. + * @return The converted span. + */ + private int convertSpanToSparseGrid(int curIx, int span, TreeSet<Integer> indexes) + { + int lastIx = curIx + span; + int retSpan = 1; + + for (Iterator<Integer> it = indexes.iterator(); it.hasNext();) { + int ix = it.next(); + if (ix <= curIx) + continue; // We have not arrive to the correct index yet + + if (ix >= lastIx) + break; + + retSpan++; + } + return retSpan; + } + + private final boolean isCellFree(int r, int c, ArrayList<int[]> occupiedRects) + { + if (getCell(r, c) != null) + return false; + + for (int i = 0; i < occupiedRects.size(); i++) { + int[] rect = occupiedRects.get(i); + if (rect[0] <= c && rect[1] <= r && rect[0] + rect[2] > c && rect[1] + rect[3] > r) + return false; + } + return true; + } + + private Cell getCell(int r, int c) + { + return grid.get(new Integer((r << 16) + c)); + } + + private void setCell(int r, int c, Cell cell) + { + if (c < 0 || c > MAX_GRID || r < 0 || r > MAX_GRID) + throw new IllegalArgumentException("Cell position out of bounds. row: " + r + ", col: " + c); + + rowIndexes.add(new Integer(r)); + colIndexes.add(new Integer(c)); + + grid.put(new Integer((r << 16) + c), cell); + } + + /** Adds a docking cell. That cell is outside the normal cell indexes. + * @param dockInsets The current dock insets. Will be updated! + * @param side top == 0, left == 1, bottom = 2, right = 3. + * @param cw The compwrap to put in a cell and add. + */ + private void addDockingCell(int[] dockInsets, int side, CompWrap cw) + { + int r, c, spanx = 1, spany = 1; + switch (side) { + case 0: + case 2: + r = side == 0 ? dockInsets[0]++ : dockInsets[2]--; + c = dockInsets[1]; + spanx = dockInsets[3] - dockInsets[1] + 1; // The +1 is for cell 0. + colIndexes.add(new Integer(dockInsets[3])); // Make sure there is a receiving cell + break; + + case 1: + case 3: + c = side == 1 ? dockInsets[1]++ : dockInsets[3]--; + r = dockInsets[0]; + spany = dockInsets[2] - dockInsets[0] + 1; // The +1 is for cell 0. + rowIndexes.add(new Integer(dockInsets[2])); // Make sure there is a receiving cell + break; + + default: + throw new IllegalArgumentException("Internal error 123."); + } + + rowIndexes.add(new Integer(r)); + colIndexes.add(new Integer(c)); + + grid.put(new Integer((r << 16) + c), new Cell(cw, spanx, spany, spanx > 1)); + } + + /** A simple representation of a cell in the grid. Contains a number of component wraps and if they span more than one cell. + */ + private static class Cell + { + private final int spanx, spany; + private final boolean flowx; + private final ArrayList<CompWrap> compWraps = new ArrayList<CompWrap>(1); + + private boolean hasTagged = false; // If one or more components have styles and need to be checked by the component sorter + + private Cell(CompWrap cw) + { + this(cw, 1, 1, true); + } + + private Cell(int spanx, int spany, boolean flowx) + { + this(null, spanx, spany, flowx); + } + + private Cell(CompWrap cw, int spanx, int spany, boolean flowx) + { + if (cw != null) + compWraps.add(cw); + this.spanx = spanx; + this.spany = spany; + this.flowx = flowx; + } + } + + /** A number of component wraps that share a layout "something" <b>in one dimension</b> + */ + private static class LinkedDimGroup + { + private static final int TYPE_SERIAL = 0; + private static final int TYPE_PARALLEL = 1; + private static final int TYPE_BASELINE = 2; + + private final String linkCtx; + private final int span; + private final int linkType; + private final boolean isHor, fromEnd; + + private ArrayList<CompWrap> _compWraps = new ArrayList<CompWrap>(4); + + private int[] sizes = null; + private int lStart = 0, lSize = 0; // Currently mostly for debug painting + + private LinkedDimGroup(String linkCtx, int span, int linkType, boolean isHor, boolean fromEnd) + { + this.linkCtx = linkCtx; + this.span = span; + this.linkType = linkType; + this.isHor = isHor; + this.fromEnd = fromEnd; + } + + private void addCompWrap(CompWrap cw) + { + _compWraps.add(cw); + sizes = null; + } + + private void setCompWraps(ArrayList<CompWrap> cws) + { + if (_compWraps != cws) { + _compWraps = cws; + sizes = null; + } + } + + private void layout(DimConstraint dc, int start, int size, int spanCount) + { + lStart = start; + lSize = size; + + if (_compWraps.size() == 0) + return; + + ContainerWrapper parent = _compWraps.get(0).comp.getParent(); + if (linkType == TYPE_PARALLEL) { + layoutParallel(parent, _compWraps, dc, start, size, isHor, spanCount, fromEnd); + } else if (linkType == TYPE_BASELINE) { + layoutBaseline(parent, _compWraps, dc, start, size, LayoutUtil.PREF, spanCount); + } else { + layoutSerial(parent, _compWraps, dc, start, size, isHor, spanCount, fromEnd); + } + } + + /** Returns the min/pref/max sizes for this cell. Returned array <b>must not be altered</b> + * @return A shared min/pref/max array of sizes. Always of length 3 and never <code>null</code>. Will always be of type STATIC and PIXEL. + */ + private int[] getMinPrefMax() + { + if (sizes == null && _compWraps.size() > 0) { + sizes = new int[3]; + for (int sType = LayoutUtil.MIN; sType <= LayoutUtil.PREF; sType++) { + if (linkType == TYPE_PARALLEL) { + sizes[sType] = getTotalSizeParallel(_compWraps, sType, isHor); + } else if (linkType == TYPE_BASELINE) { + int[] aboveBelow = getBaselineAboveBelow(_compWraps, sType, false); + sizes[sType] = aboveBelow[0] + aboveBelow[1]; + } else { + sizes[sType] = getTotalSizeSerial(_compWraps, sType, isHor); + } + } + sizes[LayoutUtil.MAX] = LayoutUtil.INF; + } + return sizes; + } + } + + /** Wraps a {@link java.awt.Component} together with its constraint. Caches a lot of information about the component so + * for instance not the preferred size has to be calculated more than once. + */ + private final static class CompWrap + { + private final ComponentWrapper comp; + private final CC cc; + private final UnitValue[] pos; + private int[][] gaps; // [top,left(actually before),bottom,right(actually after)][min,pref,max] + + private final int[] horSizes = new int[3]; + private final int[] verSizes = new int[3]; + + private int x = LayoutUtil.NOT_SET, y = LayoutUtil.NOT_SET, w = LayoutUtil.NOT_SET, h = LayoutUtil.NOT_SET; + + private int forcedPushGaps = 0; // 1 == before, 2 = after. Bitwise. + + private CompWrap(ComponentWrapper c, CC cc, int eHideMode, UnitValue[] pos, BoundSize[] callbackSz) + { + this.comp = c; + this.cc = cc; + this.pos = pos; + + if (eHideMode <= 0) { + BoundSize hBS = (callbackSz != null && callbackSz[0] != null) ? callbackSz[0] : cc.getHorizontal().getSize(); + BoundSize vBS = (callbackSz != null && callbackSz[1] != null) ? callbackSz[1] : cc.getVertical().getSize(); + + for (int i = LayoutUtil.MIN; i <= LayoutUtil.MAX; i++) { + horSizes[i] = getSize(hBS, i, true); + verSizes[i] = getSize(vBS, i, false); + } + + correctMinMax(horSizes); + correctMinMax(verSizes); + } + + if (eHideMode > 1) { + gaps = new int[4][]; + for (int i = 0; i < gaps.length; i++) + gaps[i] = new int[3]; + } + } + + private final int getSize(BoundSize uvs, int sizeType, boolean isHor) + { + if (uvs == null || uvs.getSize(sizeType) == null) { + switch(sizeType) { + case LayoutUtil.MIN: + return isHor ? comp.getMinimumWidth() : comp.getMinimumHeight(); + case LayoutUtil.PREF: + return isHor ? comp.getPreferredWidth() : comp.getPreferredHeight(); + default: + return isHor ? comp.getMaximumWidth() : comp.getMaximumHeight(); + } + } + + ContainerWrapper par = comp.getParent(); + return uvs.getSize(sizeType).getPixels(isHor ? par.getWidth() : par.getHeight(), par, comp); + } + + private final void calcGaps(ComponentWrapper before, CC befCC, ComponentWrapper after, CC aftCC, String tag, boolean flowX, boolean isLTR) + { + ContainerWrapper par = comp.getParent(); + int parW = par.getWidth(); + int parH = par.getHeight(); + + BoundSize befGap = before != null ? (flowX ? befCC.getHorizontal() : befCC.getVertical()).getGapAfter() : null; + BoundSize aftGap = after != null ? (flowX ? aftCC.getHorizontal() : aftCC.getVertical()).getGapBefore() : null; + + mergeGapSizes(cc.getVertical().getComponentGaps(par, comp, befGap, (flowX ? null : before), tag, parH, 0, isLTR), false, true); + mergeGapSizes(cc.getHorizontal().getComponentGaps(par, comp, befGap, (flowX ? before : null), tag, parW, 1, isLTR), true, true); + mergeGapSizes(cc.getVertical().getComponentGaps(par, comp, aftGap, (flowX ? null : after), tag, parH, 2, isLTR), false, false); + mergeGapSizes(cc.getHorizontal().getComponentGaps(par, comp, aftGap, (flowX ? after : null), tag, parW, 3, isLTR), true, false); + } + + private final void setDimBounds(int start, int size, boolean isHor) + { + if (isHor) { + x = start; + w = size; + } else { + y = start; + h = size; + } + } + + private final boolean isPushGap(boolean isHor, boolean isBefore) + { + if (isHor && ((isBefore ? 1 : 2) & forcedPushGaps) != 0) + return true; // Forced + + DimConstraint dc = cc.getDimConstraint(isHor); + BoundSize s = isBefore ? dc.getGapBefore() : dc.getGapAfter(); + return s != null && s.getGapPush(); + } + + /** + * @return If the preferred size have changed because of the new bounds (needed for SWT only) + */ + private final boolean transferBounds(boolean checkPrefChange) + { + comp.setBounds(x, y, w, h); + + if (checkPrefChange && w != horSizes[LayoutUtil.PREF]) { + BoundSize vSz = cc.getVertical().getSize(); + if ((vSz == null || vSz.getPreferred() == null)) { + if (comp.getPreferredHeight() != verSizes[LayoutUtil.PREF]) { + //System.out.println(comp.getComponent() + "oldPrefH: " + verSizes[LayoutUtil.PREF] + ", new: " + comp.getPreferredHeight()); + return true; + } + } + } + + return false; + } + + private final void setSizes(int[] sizes, boolean isHor) + { + if (sizes == null) + return; + + int[] s = isHor ? horSizes : verSizes; + for (int i = 0; i < 3; i++) + s[i] = sizes[i]; + } + + private void setGaps(int[] minPrefMax, int ix) + { + if (gaps == null) + gaps = new int[][] {null, null, null, null}; + + gaps[ix] = minPrefMax; + } + + private final void mergeGapSizes(int[] sizes, boolean isHor, boolean isTL) + { + if (gaps == null) + gaps = new int[][] {null, null, null, null}; + + if (sizes == null) + return; + + int gapIX = getGapIx(isHor, isTL); + int[] oldGaps = gaps[gapIX]; + if (oldGaps == null) { + oldGaps = new int[] {0, 0, LayoutUtil.INF}; + gaps[gapIX] = oldGaps; + } + + oldGaps[LayoutUtil.MIN] = Math.max(sizes[LayoutUtil.MIN], oldGaps[LayoutUtil.MIN]); + oldGaps[LayoutUtil.PREF] = Math.max(sizes[LayoutUtil.PREF], oldGaps[LayoutUtil.PREF]); + oldGaps[LayoutUtil.MAX] = Math.min(sizes[LayoutUtil.MAX], oldGaps[LayoutUtil.MAX]); + } + + private final int getGapIx(boolean isHor, boolean isTL) + { + return isHor ? (isTL ? 1 : 3) : (isTL ? 0 : 2); + } + + private final String getLinkContext(boolean defBaseline) + { + return isBaselineAlign(defBaseline) ? "baseline" : null; + } + + private final int getSizeInclGaps(int sizeType, boolean isHor) + { + return filter(sizeType, getGapBefore(sizeType, isHor) + getSize(sizeType, isHor) + getGapAfter(sizeType, isHor)); + } + + private final int getSize(int sizeType, boolean isHor) + { + return filter(sizeType, isHor ? horSizes[sizeType] : verSizes[sizeType]); + } + + private final int getGapBefore(int sizeType, boolean isHor) + { + int[] gaps = getGaps(isHor, true); + return gaps != null ? filter(sizeType, gaps[sizeType]) : 0; + } + + private final int getGapAfter(int sizeType, boolean isHor) + { + int[] gaps = getGaps(isHor, false); + return gaps != null ? filter(sizeType, gaps[sizeType]) : 0; + } + + private final int[] getGaps(boolean isHor, boolean isTL) + { + return gaps[getGapIx(isHor, isTL)]; + } + + private final int filter(int sizeType, int size) + { + if (size == LayoutUtil.NOT_SET) + return sizeType != LayoutUtil.MAX ? 0 : LayoutUtil.INF; + return constrainSize(size); + } + + private final boolean isBaselineAlign(boolean defValue) + { + Float g = cc.getVertical().getGrow(); + if (g != null && g.intValue() != 0) + return false; + + UnitValue al = cc.getVertical().getAlign(); + return comp.hasBaseline() && (al != null ? al == UnitValue.BASELINE_IDENTITY : defValue); + } + + private final int getBaseline(int sizeType) + { + return comp.getBaseline(getSize(sizeType, true), getSize(sizeType, false)); + } + } + + //*************************************************************************************** + //* Helper Methods + //*************************************************************************************** + + private static void layoutBaseline(ContainerWrapper parent, ArrayList<CompWrap> compWraps, DimConstraint dc, int start, int size, int sizeType, int spanCount) + { + int[] aboveBelow = getBaselineAboveBelow(compWraps, sizeType, true); + int blRowSize = aboveBelow[0] + aboveBelow[1]; + + CC cc = compWraps.get(0).cc; + + // Align for the whole baseline component array + UnitValue align = cc.getVertical().getAlign(); + if (spanCount == 1 && align == null) + align = dc.getAlignOrDefault(false); + if (align == UnitValue.BASELINE_IDENTITY) + align = UnitValue.CENTER; + + int offset = start + aboveBelow[0] + (align != null ? Math.max(0, align.getPixels(size - blRowSize, parent, null)) : 0); + for (int i = 0, iSz = compWraps.size(); i < iSz; i++) { + CompWrap cw = compWraps.get(i); + cw.y += offset; + + if (cw.y + cw.h > start + size) + cw.h = start + size - cw.y; + } + } + + private static void layoutSerial(ContainerWrapper parent, ArrayList<CompWrap> compWraps, DimConstraint dc, int start, int size, boolean isHor, int spanCount, boolean fromEnd) + { + FlowSizeSpec fss = mergeSizesGapsAndResConstrs( + getComponentResizeConstraints(compWraps, isHor), + getComponentGapPush(compWraps, isHor), + getComponentSizes(compWraps, isHor), + getGaps(compWraps, isHor), + 0, null); + + Float[] growW = dc.isFill() ? GROW_100 : null; + int[] sizes = LayoutUtil.calculateSerial(fss.sizes, fss.resConstsInclGaps, growW, LayoutUtil.PREF, size); + setCompWrapBounds(parent, sizes, compWraps, dc.getAlignOrDefault(isHor), start, size, isHor, fromEnd); + } + + private static void setCompWrapBounds(ContainerWrapper parent, int[] allSizes, ArrayList<CompWrap> compWraps, UnitValue rowAlign, int start, int size, boolean isHor, boolean fromEnd) + { + int totSize = LayoutUtil.sum(allSizes); + CC cc = compWraps.get(0).cc; + UnitValue align = correctAlign(cc, rowAlign, isHor, fromEnd); + + int cSt = start; + int slack = size - totSize; + if (slack > 0 && align != null) { + int al = Math.min(slack, Math.max(0, align.getPixels(slack, parent, null))); + cSt += (fromEnd ? -al : al); + } + + for (int i = 0, bIx = 0, iSz = compWraps.size(); i < iSz; i++) { + CompWrap cw = compWraps.get(i); + if (fromEnd ) { + cSt -= allSizes[bIx++]; + cw.setDimBounds(cSt - allSizes[bIx], allSizes[bIx], isHor); + cSt -= allSizes[bIx++]; + } else { + cSt += allSizes[bIx++]; + cw.setDimBounds(cSt, allSizes[bIx], isHor); + cSt += allSizes[bIx++]; + } + } + } + + private static void layoutParallel(ContainerWrapper parent, ArrayList<CompWrap> compWraps, DimConstraint dc, int start, int size, boolean isHor, int spanCount, boolean fromEnd) + { + int[][] sizes = new int[compWraps.size()][]; // [compIx][gapBef,compSize,gapAft] + + for (int i = 0; i < sizes.length; i++) { + CompWrap cw = compWraps.get(i); + + DimConstraint cDc = cw.cc.getDimConstraint(isHor); + + ResizeConstraint[] resConstr = new ResizeConstraint[] { + cw.isPushGap(isHor, true) ? GAP_RC_CONST_PUSH : GAP_RC_CONST, + cDc.resize, + cw.isPushGap(isHor, false) ? GAP_RC_CONST_PUSH : GAP_RC_CONST, + }; + + int[][] sz = new int[][] { + cw.getGaps(isHor, true), (isHor ? cw.horSizes : cw.verSizes), cw.getGaps(isHor, false) + }; + + Float[] growW = dc.isFill() ? GROW_100 : null; + + sizes[i] = LayoutUtil.calculateSerial(sz, resConstr, growW, LayoutUtil.PREF, size); + } + + UnitValue rowAlign = dc.getAlignOrDefault(isHor); + setCompWrapBounds(parent, sizes, compWraps, rowAlign, start, size, isHor, fromEnd); + } + + private static void setCompWrapBounds(ContainerWrapper parent, int[][] sizes, ArrayList<CompWrap> compWraps, UnitValue rowAlign, int start, int size, boolean isHor, boolean fromEnd) + { + for (int i = 0; i < sizes.length; i++) { + CompWrap cw = compWraps.get(i); + + UnitValue align = correctAlign(cw.cc, rowAlign, isHor, fromEnd); + + int[] cSizes = sizes[i]; + int gapBef = cSizes[0]; + int cSize = cSizes[1]; // No Math.min(size, cSizes[1]) here! + int gapAft = cSizes[2]; + + int cSt = fromEnd ? start - gapBef : start + gapBef; + int slack = size - cSize - gapBef - gapAft; + if (slack > 0 && align != null) { + int al = Math.min(slack, Math.max(0, align.getPixels(slack, parent, null))); + cSt += (fromEnd ? -al : al); + } + + cw.setDimBounds(fromEnd ? cSt - cSize : cSt, cSize, isHor); + } + } + + private static UnitValue correctAlign(CC cc, UnitValue rowAlign, boolean isHor, boolean fromEnd) + { + UnitValue align = (isHor ? cc.getHorizontal() : cc.getVertical()).getAlign(); + if (align == null) + align = rowAlign; + if (align == UnitValue.BASELINE_IDENTITY) + align = UnitValue.CENTER; + + if (fromEnd) { + if (align == UnitValue.LEFT) + align = UnitValue.RIGHT; + else if (align == UnitValue.RIGHT) + align = UnitValue.LEFT; + } + return align; + } + + private static int[] getBaselineAboveBelow(ArrayList<CompWrap> compWraps, int sType, boolean centerBaseline) + { + int maxAbove = Short.MIN_VALUE; + int maxBelow = Short.MIN_VALUE; + for (int i = 0, iSz = compWraps.size(); i < iSz; i++) { + CompWrap cw = compWraps.get(i); + + int height = cw.getSize(sType, false); + if (height >= LayoutUtil.INF) + return new int[] {LayoutUtil.INF / 2, LayoutUtil.INF / 2}; + + int baseline = cw.getBaseline(sType); + int above = baseline + cw.getGapBefore(sType, false); + maxAbove = Math.max(above, maxAbove); + maxBelow = Math.max(height - baseline + cw.getGapAfter(sType, false), maxBelow); + + if (centerBaseline) + cw.setDimBounds(-baseline, height, false); + } + return new int[] {maxAbove, maxBelow}; + } + + private static int getTotalSizeParallel(ArrayList<CompWrap> compWraps, int sType, boolean isHor) + { + int size = sType == LayoutUtil.MAX ? LayoutUtil.INF : 0; + + for (int i = 0, iSz = compWraps.size(); i < iSz; i++) { + CompWrap cw = compWraps.get(i); + int cwSize = cw.getSizeInclGaps(sType, isHor); + if (cwSize >= LayoutUtil.INF) + return LayoutUtil.INF; + + if (sType == LayoutUtil.MAX ? cwSize < size : cwSize > size) + size = cwSize; + } + return constrainSize(size); + } + + private static final int getTotalSizeSerial(ArrayList<CompWrap> compWraps, int sType, boolean isHor) + { + int totSize = 0; + for (int i = 0, iSz = compWraps.size(), lastGapAfter = 0; i < iSz; i++) { + CompWrap wrap = compWraps.get(i); + int gapBef = wrap.getGapBefore(sType, isHor); + if (gapBef > lastGapAfter) + totSize += gapBef - lastGapAfter; + + totSize += wrap.getSize(sType, isHor); + totSize += (lastGapAfter = wrap.getGapAfter(sType, isHor)); + + if (totSize >= LayoutUtil.INF) + return LayoutUtil.INF; + } + return constrainSize(totSize); + } + + private static final int getTotalGroupsSizeParallel(ArrayList<LinkedDimGroup> groups, int sType, boolean countSpanning) + { + int size = sType == LayoutUtil.MAX ? LayoutUtil.INF : 0; + for (int i = 0, iSz = groups.size(); i < iSz; i++) { + LinkedDimGroup group = groups.get(i); + if (countSpanning || group.span == 1) { + int grpSize = group.getMinPrefMax()[sType]; + if (grpSize >= LayoutUtil.INF) + return LayoutUtil.INF; + + if (sType == LayoutUtil.MAX ? grpSize < size : grpSize > size) + size = grpSize; + } + } + return constrainSize(size); + } + + /** + * @param compWraps + * @param isHor + * @return Might contain LayoutUtil.NOT_SET + */ + private static int[][] getComponentSizes(ArrayList<CompWrap> compWraps, boolean isHor) + { + int[][] compSizes = new int[compWraps.size()][]; + for (int i = 0; i < compSizes.length; i++) { + CompWrap cw = compWraps.get(i); + compSizes[i] = isHor ? cw.horSizes : cw.verSizes; + } + return compSizes; + } + + /** Merges sizes and gaps together with Resize Constraints. For gaps {@link #GAP_RC_CONST} is used. + * @param resConstr One resize constriant for every row/component. Can be lesser in length and the last element should be used for missing elements. + * @param gapPush If the corresponding gap should be considered pushing and thus want to take free space if left over. Should be one more than resConstrs! + * @param minPrefMaxSizes The sizes (min/pref/max) for every row/component. + * @param gapSizes The gaps before and after each row/component packed in one double sized array. + * @param refSize The reference size to get the gap in pixels. + * @param parent The parent used to get the gap in pixels. + * @return A holder for the merged values. + */ + private static FlowSizeSpec mergeSizesGapsAndResConstrs(ResizeConstraint[] resConstr, boolean[] gapPush, int[][] minPrefMaxSizes, int[][] gapSizes, int refSize, ContainerWrapper parent) + { + int[][] sizes = new int[(minPrefMaxSizes.length << 1) + 1][]; // Make room for gaps around. + ResizeConstraint[] resConstsInclGaps = new ResizeConstraint[sizes.length]; + + sizes[0] = gapSizes[0]; + for (int i = 0, crIx = 1; i < minPrefMaxSizes.length; i++, crIx += 2) { + + // Component bounds and constraints + resConstsInclGaps[crIx] = resConstr[i]; + sizes[crIx] = minPrefMaxSizes[i]; + + sizes[crIx + 1] = gapSizes[i + 1]; + + if (sizes[crIx - 1] != null) + resConstsInclGaps[crIx - 1] = gapPush[i < gapPush.length ? i : gapPush.length - 1] ? GAP_RC_CONST_PUSH : GAP_RC_CONST; + + if (i == (minPrefMaxSizes.length - 1) && sizes[crIx + 1] != null) + resConstsInclGaps[crIx + 1] = gapPush[(i + 1) < gapPush.length ? (i + 1) : gapPush.length - 1] ? GAP_RC_CONST_PUSH : GAP_RC_CONST; + } + + // Check for null and set it to 0, 0, 0. + for (int i = 0; i < sizes.length; i++) { + if (sizes[i] == null) + sizes[i] = new int[3]; + } + + return new FlowSizeSpec(sizes, resConstsInclGaps); + } + + private static final int[] mergeSizes(int[] oldValues, int[] newValues) + { + if (oldValues == null) + return newValues; + + if (newValues == null) + return oldValues; + + int[] ret = new int[oldValues.length]; + for (int i = 0; i < ret.length; i++) + ret[i] = mergeSizes(oldValues[i], newValues[i], true); + + return ret; + } + + private static final int mergeSizes(int oldValue, int newValue, boolean toMax) + { + if (oldValue == LayoutUtil.NOT_SET || oldValue == newValue) + return newValue; + + if (newValue == LayoutUtil.NOT_SET) + return oldValue; + + return toMax != oldValue > newValue ? newValue : oldValue; + } + + private static final int constrainSize(int s) + { + return s > 0 ? (s < LayoutUtil.INF ? s : LayoutUtil.INF) : 0; + } + + private static final void correctMinMax(int s[]) + { + if (s[LayoutUtil.MIN] > s[LayoutUtil.MAX]) + s[LayoutUtil.MIN] = s[LayoutUtil.MAX]; // Since MAX is almost always explicitly set use tha + + if (s[LayoutUtil.PREF] < s[LayoutUtil.MIN]) + s[LayoutUtil.PREF] = s[LayoutUtil.MIN]; + + if (s[LayoutUtil.PREF] > s[LayoutUtil.MAX]) + s[LayoutUtil.PREF] = s[LayoutUtil.MAX]; + } + + private static final class FlowSizeSpec + { + private final int[][] sizes; + private final ResizeConstraint[] resConstsInclGaps; + + private FlowSizeSpec(int[][] sizes, ResizeConstraint[] resConstsInclGaps) + { + this.sizes = sizes; + this.resConstsInclGaps = resConstsInclGaps; + } + + /** + * @param specs The specs for the columns or rows. Last index will be used of <code>fromIx + len</code> is greater than this array's length. + * @param targetSize The size to try to meat. + * @param defGrow The default grow weight if the specs does not have anyone that will grow. Comes from "push" in the CC. + * @param fromIx + * @param len + * @param sizeType + * @param eagerness How eager the algorithm should be to try to expand the sizes. + * <ul> + * <li>0 - Grow only rows/columns which has the <code>sizeType</code> set to be the containing components AND which has a grow weight > 0. + * <li>1 - Grow only rows/columns which has the <code>sizeType</code> set to be the containing components AND which has a grow weight > 0 OR unspecified. + * <li>2 - Grow all rows/columns that has a grow weight > 0. + * <li>3 - Grow all rows/columns that has a grow weight > 0 OR unspecified. + * </ul> + * @return The new size. + */ + private final int expandSizes(DimConstraint[] specs, Float[] defGrow, int targetSize, int fromIx, int len, int sizeType, int eagerness) + { + ResizeConstraint[] resConstr = new ResizeConstraint[len]; + int[][] sizesToExpand = new int[len][]; + for (int i = 0; i < len; i++) { + int size = sizes[i + fromIx][sizeType]; + sizesToExpand[i] = new int[] {size, size, sizes[i + fromIx][LayoutUtil.MAX]}; + + if (eagerness <= 1 && i % 2 == 0) { // // (i % 2 == 0) means only odd indexes, which is only rows/col indexes and not gaps. + int cIx = (i + fromIx - 1) >> 1; + DimConstraint spec = (DimConstraint) LayoutUtil.getIndexSafe(specs, cIx); + + if ( (sizeType == LayoutUtil.MIN && spec.getSize() != null && spec.getSize().getMin() != null && spec.getSize().getMin().getUnit() != UnitValue.MIN_SIZE) || + (sizeType == LayoutUtil.PREF && spec.getSize() != null && spec.getSize().getPreferred() != null && spec.getSize().getPreferred().getUnit() != UnitValue.PREF_SIZE)) { + continue; + } + } + resConstr[i] = (ResizeConstraint) LayoutUtil.getIndexSafe(resConstsInclGaps, i + fromIx); + } + + Float[] growW = (eagerness == 1 || eagerness == 3) ? extractSubArray(specs, defGrow, fromIx, len): null; + int[] newSizes = LayoutUtil.calculateSerial(sizesToExpand, resConstr, growW, sizeType, targetSize); + int newSize = 0; + + for (int i = 0; i < len; i++) { + int s = newSizes[i]; + sizes[i + fromIx][sizeType] = s; + newSize += s; + } + return newSize; + } + } + + private static Float[] extractSubArray(DimConstraint[] specs, Float[] arr, int ix, int len) + { + if (arr == null || arr.length < ix + len) { + Float[] growLastArr = new Float[len]; + + // Handle a group where some rows (first one/few and/or last one/few) are docks. + for (int i = ix + len - 1; i >= 0; i -= 2) { + int specIx = (i >> 1); + if (specs[specIx] != DOCK_DIM_CONSTRAINT) { + growLastArr[i - ix] = ResizeConstraint.WEIGHT_100; + return growLastArr; + } + } + return growLastArr; + } + + Float[] newArr = new Float[len]; + for (int i = 0; i < len; i++) + newArr[i] = arr[ix + i]; + return newArr; + } + + private static WeakHashMap[] PARENT_ROWCOL_SIZES_MAP = null; + static synchronized void putSizesAndIndexes(Object parComp, int[] sizes, int[] ixArr, boolean isRows) + { + if (PARENT_ROWCOL_SIZES_MAP == null) // Lazy since only if designing in IDEs + PARENT_ROWCOL_SIZES_MAP = new WeakHashMap[] {new WeakHashMap(4), new WeakHashMap(4)}; + + PARENT_ROWCOL_SIZES_MAP[isRows ? 0 : 1].put(parComp, new int[][] {ixArr, sizes}); + } + + static synchronized int[][] getSizesAndIndexes(Object parComp, boolean isRows) + { + if (PARENT_ROWCOL_SIZES_MAP == null) + return null; + + return (int[][]) PARENT_ROWCOL_SIZES_MAP[isRows ? 0 : 1].get(parComp); + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/IDEUtil.java b/prototypes/miglayout/net/miginfocom/layout/IDEUtil.java index b52d37df..600bb810 100644 --- a/prototypes/miglayout/net/miginfocom/layout/IDEUtil.java +++ b/prototypes/miglayout/net/miginfocom/layout/IDEUtil.java @@ -1,704 +1,704 @@ -package net.miginfocom.layout;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** This class contains static methods to be used by IDE vendors to convert to and from String/API constraints.
- * <p>
- * <b>Note that {@link LayoutUtil#setDesignTime(boolean)} should be set to <code>true</code> for this class'
- * methods to work.</b>
- */
-public class IDEUtil
-{
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue ZERO = UnitValue.ZERO;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue TOP = UnitValue.TOP;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue LEADING = UnitValue.LEADING;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue LEFT = UnitValue.LEFT;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue CENTER = UnitValue.CENTER;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue TRAILING = UnitValue.TRAILING;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue RIGHT = UnitValue.RIGHT;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue BOTTOM = UnitValue.BOTTOM;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue LABEL = UnitValue.LABEL;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue INF = UnitValue.INF;
-
- /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}.
- */
- public static final UnitValue BASELINE_IDENTITY = UnitValue.BASELINE_IDENTITY;
-
- private final static String[] X_Y_STRINGS = new String[] {"x", "y", "x2", "y2"};
-
- /** Returns the sizes of the rows and gaps for a container. * There will be two arrays returned [0] and [1].
- * <p>
- * The first array will be the indexes of the rows where indexes that
- * are less than 30000 or larger than 30000 is docking rows. There might be extra docking rows that aren't
- * visible but they always have size 0. Non docking indexes will probably always be 0, 1, 2, 3, etc..
- * <p>
- * The second array is the sizes of the form:<br>
- * <code>[left inset][row size 1][gap 1][row size 2][gap 2][row size n][right inset]</code>.
- * <p>
- * The returned sizes will be the ones calculated in the last layout cycle.
- * @param parentContainer The container to retuern the row sizes and gaps for. In Swing it will be a {@link java.awt.Container} and
- * in SWT it will be a {@link org.eclipse.swt.widgets.Composite}.
- * @return The sizes or <code>null</code> if {@link LayoutUtil#isDesignTime()} is <code>false</code> or
- * <code>parentContainer</code> does not have a MigLayout layout manager.
- * The returned sizes will be the ones calculated in the last layout cycle.
- * @see LayoutUtil#isDesignTime()
- */
- public static int[][] getRowSizes(Object parentContainer)
- {
- return Grid.getSizesAndIndexes(parentContainer, true);
- }
-
- /** Returns the sizes of the columns and gaps for a container.
- * There will be two arrays returned [0] and [1].
- * <p>
- * The first array will be the indexes of the columns where indexes that
- * are less than 30000 or larger than 30000 is docking columns. There might be extra docking columns that aren't
- * visible but they always have size 0. Non docking indexes will probably always be 0, 1, 2, 3, etc..
- * <p>
- * The second array is the sizes of the form:<br>
- * <code>[top inset][column size 1][gap 1][column size 2][gap 2][column size n][bottom inset]</code>.
- * <p>
- * The returned sizes will be the ones calculated in the last layout cycle.
- * @param parentContainer The container to retuern the column sizes and gaps for. In Swing it will be a {@link java.awt.Container} and
- * in SWT it will be a {@link org.eclipse.swt.widgets.Composite}.
- * @return The sizes and indexes or <code>null</code> if {@link LayoutUtil#isDesignTime()} is <code>false</code> or
- * <code>parentContainer</code> does not have a MigLayout layout manager.
- * The returned sizes will be the ones calculated in the last layout cycle.
- * @see LayoutUtil#isDesignTime()
- */
- public static int[][] getColumnSizes(Object parentContainer)
- {
- return Grid.getSizesAndIndexes(parentContainer, false);
- }
-
- /** Returns the a constraint string that can be re-parsed to be the exact same AxisConstraint.
- * @param ac The axis constraint to return as a constraint string.
- * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
- * as a String type (e.g. "flowx, gap rel, right").
- * @param isCols The the constraint should be returned for columns rather than rows.
- * @return A String. Never <code>null</code>.
- */
- public static final String getConstraintString(AC ac, boolean asAPI, boolean isCols)
- {
- StringBuffer sb = new StringBuffer(32);
-
- DimConstraint[] dims = ac.getConstaints();
- BoundSize defGap = isCols ? PlatformDefaults.getGridGapX() : PlatformDefaults.getGridGapY();
-
- for (int i = 0; i < dims.length; i++) {
- DimConstraint dc = dims[i];
-
- addRowDimConstraintString(dc, sb, asAPI);
-
- if (i < dims.length - 1) {
- BoundSize gapAft = dc.getGapAfter();
- BoundSize gapBefNext = dims[i + 1].getGapBefore();
-
- if (gapAft != null && gapAft == gapBefNext && gapAft != defGap) {
- if (asAPI) {
- sb.append(".gap(\"").append(getBS(gapAft)).append("\")");
- } else {
- sb.append(getBS(gapAft));
- }
- } else {
- if (asAPI)
- sb.append(".gap()");
- }
- }
- }
-
- return sb.toString();
- }
-
- /** Adds the a constraint string that can be re-parsed to be the exact same DimConstraint.
- * @param dc The layout constraint to return as a constraint string.
- * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
- * as a String type (e.g. "flowx, gap rel, right").
- */
- private static final void addRowDimConstraintString(DimConstraint dc, StringBuffer sb, boolean asAPI)
- {
- int gp = dc.getGrowPriority();
-
- int firstComma = sb.length();
-
- BoundSize size = dc.getSize();
- if (size != null) {
- if (asAPI) {
- sb.append(".size(\"").append(getBS(size)).append("\")");
- } else {
- sb.append(',').append(getBS(size));
- }
- }
-
- if (gp != 100) {
- if (asAPI) {
- sb.append(".growPrio(").append(gp).append("\")");
- } else {
- sb.append(",growprio ").append(gp);
- }
- }
-
- Float gw = dc.getGrow();
- if (gw != null) {
- String g = gw.floatValue() != 100f ? LayoutUtil.floatToString(gw.floatValue()) : "";
- if (asAPI) {
- if (g.length() == 0) {
- sb.append(".grow()");
- } else {
- sb.append(".grow(\"").append(g).append("\")");
- }
- } else {
- sb.append(",grow").append(g.length() > 0 ? (" " + g) : "");
- }
- }
-
- int sp = dc.getShrinkPriority();
- if (sp != 100) {
- if (asAPI) {
- sb.append(".shrinkPrio(").append(sp).append("\")");
- } else {
- sb.append(",shrinkprio ").append(sp);
- }
- }
-
- Float sw = dc.getShrink();
- if (sw != null && sw.intValue() != 100) {
- String s = LayoutUtil.floatToString(sw.floatValue());
- if (asAPI) {
- sb.append(".shrink(\"").append(s).append("\")");
- } else {
- sb.append(",shrink ").append(s);
- }
- }
-
- String eg = dc.getEndGroup();
- if (eg != null) {
- if (asAPI) {
- sb.append(".endGroup(\"").append(eg).append("\")");
- } else {
- sb.append(",endgroup ").append(eg);
- }
- }
-
- String sg = dc.getSizeGroup();
- if (sg != null) {
- if (asAPI) {
- sb.append(".sizeGroup(\"").append(sg).append("\")");
- } else {
- sb.append(",sizegroup ").append(sg);
- }
- }
-
- UnitValue al = dc.getAlign();
- if (al != null) {
- if (asAPI) {
- sb.append(".align(\"").append(getUV(al)).append("\")");
- } else {
- String s = getUV(al);
- String alKw = (s.equals("top") || s.equals("bottom") || s.equals("left") || s.equals("label") ||
- s.equals("leading") || s.equals("center") || s.equals("trailing") ||
- s.equals("right") || s.equals("baseline")) ? "" : "align ";
- sb.append(',').append(alKw).append(s);
- }
- }
-
- if (dc.isNoGrid()) {
- if (asAPI) {
- sb.append(".noGrid()");
- } else {
- sb.append(",nogrid");
- }
- }
-
- if (dc.isFill()) {
- if (asAPI) {
- sb.append(".fill()");
- } else {
- sb.append(",fill");
- }
- }
-
- if (asAPI == false) {
- if (sb.length() > firstComma) {
- sb.setCharAt(firstComma, '[');
- sb.append(']');
- } else {
- sb.append("[]");
- }
- }
- }
-
- /** Returns the a constraint string that can be re-parsed to be the exact same DimConstraint.
- * @param dc The layout constraint to return as a constraint string.
- * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
- * as a String type (e.g. "flowx, gap rel, right").
- * @param isHor The the DimConstraint is decoration something horizontal (column or x).
- * @param noGrowAdd If <code>true</code> no grow constraints will be added.
- * @return A constraint string. Never <code>null</code>.
- */
- private static final void addComponentDimConstraintString(DimConstraint dc, StringBuffer sb, boolean asAPI, boolean isHor, boolean noGrowAdd)
- {
- int gp = dc.getGrowPriority();
- if (gp != 100) {
- if (asAPI) {
- sb.append(isHor ? ".growPrioX(" : ".growPrioY(").append(gp).append(')');
- } else {
- sb.append(isHor ? ",growpriox " : ",growprioy ").append(gp);
- }
- }
-
- if (noGrowAdd == false) {
- Float gw = dc.getGrow();
- if (gw != null) {
- String g = gw.floatValue() != 100f ? LayoutUtil.floatToString(gw.floatValue()) : "";
- if (asAPI) {
- sb.append(isHor ? ".growX(" : ".growY(").append(g).append(')');
- } else {
- sb.append(isHor ? ",growx" : ",growy").append(g.length() > 0 ? (" " + g) : "");
- }
- }
- }
-
- int sp = dc.getShrinkPriority();
- if (sp != 100) {
- if (asAPI) {
- sb.append(isHor ? ".shrinkPrioX(" : ".shrinkPrioY(").append(sp).append(')');
- } else {
- sb.append(isHor ? ",shrinkpriox " : ",shrinkprioy ").append(sp);
- }
- }
-
- Float sw = dc.getShrink();
- if (sw != null && sw.intValue() != 100) {
- String s = LayoutUtil.floatToString(sw.floatValue());
- if (asAPI) {
- sb.append(isHor ? ".shrinkX(" : ".shrinkY(").append(s).append(')');
- } else {
- sb.append(isHor ? ",shrinkx " : ",shrinky ").append(s);
- }
- }
-
- String eg = dc.getEndGroup();
- if (eg != null) {
- if (asAPI) {
- sb.append(isHor ? ".endGroupX(\"" : ".endGroupY(\"").append(eg).append("\")");
- } else {
- sb.append(isHor ? ",endgroupx " : ",endgroupy ").append(eg);
- }
- }
-
- String sg = dc.getSizeGroup();
- if (sg != null) {
- if (asAPI) {
- sb.append(isHor ? ".sizeGroupX(\"" : ".sizeGroupY(\"").append(sg).append("\")");
- } else {
- sb.append(isHor ? ",sizegroupx " : ",sizegroupy ").append(sg);
- }
- }
-
- BoundSize size = dc.getSize();
- if (size != null) {
- if (size.getPreferred() == null) {
- if (size.getMin() == null) {
- if (asAPI) {
- sb.append(isHor ? ".maxWidth(\"" : ".maxHeight(\"").append(getBS(size)).append("\")");
- } else {
- sb.append(isHor ? ",wmax " : ",hmax ").append(getBS(size));
- }
-
- } else if (size.getMax() == null) {
- if (asAPI) {
- sb.append(isHor ? ".minWidth(\"" : ".minHeight(\"").append(getBS(size)).append("\")");
- } else {
- sb.append(isHor ? ",wmin " : ",hmin ").append(getBS(size));
- }
- }
- } else {
- if (asAPI) {
- sb.append(isHor ? ".width(\"" : ".height(\"").append(getBS(size)).append("\")");
- } else {
- sb.append(isHor ? ",width " : ",height ").append(getBS(size));
- }
- }
- }
-
- UnitValue al = dc.getAlign();
- if (al != null) {
- if (asAPI) {
- sb.append(isHor ? ".alignX(\"" : ".alignY(\"").append(getUV(al)).append("\")");
- } else {
- sb.append(isHor ? ",alignx " : ",aligny ").append(getUV(al));
- }
- }
-
- BoundSize gapBef = dc.getGapBefore();
- BoundSize gapAft= dc.getGapAfter();
- if (gapBef != null || gapAft != null) {
- if (asAPI) {
- sb.append(isHor ? ".gapX(\"" : ".gapY(\"").append(getBS(gapBef)).append("\", \"").append(getBS(gapAft)).append("\")");
- } else {
- sb.append(isHor ? ",gapx " : ",gapy ").append(getBS(gapBef)).append(' ').append(getBS(gapAft));
- }
- }
- }
-
- /** Returns the a constraint string that can be re-parsed to be the exact same LayoutConstraint.
- * @param cc The component constraint to return as a constraint string.
- * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
- * as a String type (e.g. "flowx, gap rel, right").
- * @return A String. Never <code>null</code>.
- */
- public static final String getConstraintString(CC cc, boolean asAPI)
- {
- StringBuffer sb = new StringBuffer(16);
-
- if (cc.isNewline())
- sb.append(asAPI ? ".newline()" : ",newline");
-
- if (cc.isExternal())
- sb.append(asAPI ? ".external()" : ",external");
-
- Boolean flowX = cc.getFlowX();
- if (flowX != null) {
- if (asAPI) {
- sb.append(flowX.booleanValue() ? ".flowX()" : ".flowY()");
- } else {
- sb.append(flowX.booleanValue() ? ",flowx" : ",flowy");
- }
- }
-
- UnitValue[] pad = cc.getPadding();
- if (pad != null) {
- sb.append(asAPI ? ".pad(\"" : ",pad ");
- for (int i = 0; i < pad.length; i++)
- sb.append(getUV(pad[i])).append(i < pad.length - 1 ? " " : "");
- if (asAPI)
- sb.append("\")");
- }
-
- UnitValue[] pos = cc.getPos();
- if (pos != null) {
- if (cc.isBoundsInGrid()) {
- for (int i = 0; i < 4; i++) {
- if (pos[i] != null) {
- if (asAPI) {
- sb.append('.').append(X_Y_STRINGS[i]).append("(\"").append(getUV(pos[i])).append("\")");
- } else {
- sb.append(',').append(X_Y_STRINGS[i]).append(getUV(pos[i]));
- }
- }
- }
- } else {
- sb.append(asAPI ? ".pos(\"" : ",pos ");
- int iSz = (pos[2] != null || pos[3] != null) ? 4 : 2; // "pos x y" vs "pos x1 y1 x2 y2".
- for (int i = 0; i < iSz; i++)
- sb.append(getUV(pos[i])).append(i < iSz - 1 ? " " : "");
-
- if (asAPI)
- sb.append("\")");
- }
- }
-
- String id = cc.getId();
- if (id != null) {
- if (asAPI) {
- sb.append(".id(\"").append(id).append("\")");
- } else {
- sb.append(",id ").append(id);
- }
- }
-
- String tag = cc.getTag();
- if (tag != null) {
- if (asAPI) {
- sb.append(".tag(\"").append(tag).append("\")");
- } else {
- sb.append(",tag ").append(tag);
- }
- }
-
- int hideMode = cc.getHideMode();
- if (hideMode >= 0) {
- if (asAPI) {
- sb.append(".hideMode(").append(hideMode).append(')');
- } else {
- sb.append(",hideMode ").append(hideMode);
- }
- }
-
- int skip = cc.getSkip();
- if (skip > 0) {
- if (asAPI) {
- sb.append(".skip(").append(skip).append(')');
- } else {
- sb.append(",skip ").append(skip);
- }
- }
-
- int split = cc.getSplit();
- if (split > 1) {
- String s = split == LayoutUtil.INF ? "" : String.valueOf(split);
- if (asAPI) {
- sb.append(".split(").append(s).append(')');
- } else {
- sb.append(",split ").append(s);
- }
- }
-
- int cx = cc.getCellX();
- int cy = cc.getCellY();
- int spanX = cc.getSpanX();
- int spanY = cc.getSpanY();
- if (cx >= 0 && cy >= 0) {
- if (asAPI) {
- sb.append(".cell(").append(cx).append(", ").append(cy);
- if (spanX > 1 || spanY > 1)
- sb.append(", ").append(spanX).append(", ").append(spanY);
- sb.append(')');
- } else {
- sb.append(",cell ").append(cx).append(' ').append(cy);
- if (spanX > 1 || spanY > 1)
- sb.append(' ').append(spanX).append(' ').append(spanY);
- }
- } else if (spanX > 1 || spanY > 1) {
- if (spanX > 1 && spanY > 1) {
- sb.append(asAPI ? ".span(" : ",span ").append(spanX).append(asAPI ? ", " : " ").append(spanY);
- } else if (spanX > 1) {
- sb.append(asAPI ? ".spanX(" : ",spanx ").append(spanX == LayoutUtil.INF ? "" : (String.valueOf(spanX)));
- } else if (spanY > 1) {
- sb.append(asAPI ? ".spanY(" : ",spany ").append(spanY == LayoutUtil.INF ? "" : (String.valueOf(spanY)));
- }
- if (asAPI)
- sb.append(')');
- }
-
- Float pushX = cc.getPushX();
- Float pushY = cc.getPushY();
- if (pushX != null || pushY != null) {
- if (pushX != null && pushY != null) {
- sb.append(asAPI ? ".push(" : ",push ");
- if (pushX != 100.0 || pushY != 100.0)
- sb.append(pushX).append(asAPI ? ", " : " ").append(pushY);
- } else if (pushX != null) {
- sb.append(asAPI ? ".pushX(" : ",pushx ").append(pushX == 100 ? "" : (String.valueOf(pushX)));
- } else if (pushY != null) {
- sb.append(asAPI ? ".pushY(" : ",pushy ").append(pushY == 100 ? "" : (String.valueOf(pushY)));
- }
- if (asAPI)
- sb.append(')');
- }
-
- int dock = cc.getDockSide();
- if (dock >= 0) {
- String ds = CC.DOCK_SIDES[dock];
- if (asAPI) {
- sb.append(".dock").append(Character.toUpperCase(ds.charAt(0))).append(ds.substring(1)).append("()");
- } else {
- sb.append(",").append(ds);
- }
- }
-
- boolean noGrowAdd = cc.getHorizontal().getGrow() != null && cc.getHorizontal().getGrow().intValue() == 100 &&
- cc.getVertical().getGrow() != null && cc.getVertical().getGrow().intValue() == 100;
-
- addComponentDimConstraintString(cc.getHorizontal(), sb, asAPI, true, noGrowAdd);
- addComponentDimConstraintString(cc.getVertical(), sb, asAPI, false, noGrowAdd);
- if (noGrowAdd)
- sb.append(asAPI ? ".grow()" : ",grow"); // Combine ".growX().growY()" into ".grow()".
-
- if (cc.isWrap())
- sb.append(asAPI ? ".wrap()" : ",wrap");
-
- String s = sb.toString();
- return s.length() == 0 || s.charAt(0) != ',' ? s : s.substring(1);
- }
-
- /** Returns the a constraint string that can be re-parsed to be the exact same LayoutConstraint.
- * @param lc The layout constraint to return as a constraint string.
- * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or
- * as a String type (e.g. "flowx, gap rel, right").
- * @return A String. Never <code>null</code>.
- */
- public static final String getConstraintString(LC lc, boolean asAPI)
- {
- StringBuffer sb = new StringBuffer(16);
-
- if (lc.isFlowX() == false)
- sb.append(asAPI ? ".flowY()" : ",flowy");
-
- boolean fillX = lc.isFillX();
- boolean fillY = lc.isFillY();
- if (fillX || fillY) {
- if (fillX == fillY) {
- sb.append(asAPI ? ".fill()" : ",fill");
- } else {
- sb.append(asAPI ? (fillX ? ".fillX()" : ".fillY()") : (fillX ? ",fillx" : ",filly"));
- }
- }
-
- Boolean leftToRight = lc.getLeftToRight();
- if (leftToRight != null) {
- if (asAPI) {
- sb.append(".leftToRight(").append(leftToRight).append(')');
- } else {
- sb.append(leftToRight.booleanValue() ? ",ltr" : ",rtl");
- }
- }
-
- if (lc.isTopToBottom() == false)
- sb.append(asAPI ? ".bottomToTop()" : ",btt");
-
- UnitValue[] insets = lc.getInsets();
- if (insets != null) {
- String cs = LayoutUtil.getCCString(insets);
- if (cs != null) {
- if (asAPI) {
- sb.append(".insets(\"").append(cs).append("\")");
- } else {
- sb.append(",insets ").append(cs);
- }
- } else {
- sb.append(asAPI ? ".insets(\"" : ",insets ");
- for (int i = 0; i < insets.length; i++)
- sb.append(getUV(insets[i])).append(i < insets.length - 1 ? " " : "");
- if (asAPI)
- sb.append("\")");
- }
- }
-
- if (lc.isNoGrid())
- sb.append(asAPI ? ".noGrid()" : ",nogrid");
-
- if (lc.isVisualPadding() == false)
- sb.append(asAPI ? ".noVisualPadding()" : ",novisualpadding");
-
- int hideMode = lc.getHideMode();
- if (hideMode > 0) {
- if (asAPI) {
- sb.append(".hideMode(").append(hideMode).append(')');
- } else {
- sb.append(",hideMode ").append(hideMode);
- }
- }
-
- UnitValue alignX = lc.getAlignX();
- UnitValue alignY = lc.getAlignY();
- if (alignX != null || alignY != null) {
- if (alignX != null && alignY != null) {
- sb.append(asAPI ? ".align(\"" : ",align ").append(getUV(alignX)).append(' ').append(getUV(alignY));
- } else if (alignX != null) {
- sb.append(asAPI ? ".alignX(\"" : ",alignx ").append(getUV(alignX));
- } else if (alignY != null) {
- sb.append(asAPI ? ".alignY(\"" : ",aligny ").append(getUV(alignY));
- }
- if (asAPI)
- sb.append("\")");
- }
-
- BoundSize gridGapX = lc.getGridGapX();
- BoundSize gridGapY = lc.getGridGapY();
- if (gridGapX != null || gridGapY != null) {
- if (gridGapX != null && gridGapY != null) {
- sb.append(asAPI ? ".gridGap(\"" : ",gap ").append(getBS(gridGapX)).append(' ').append(getBS(gridGapY));
- } else if (gridGapX != null) {
- sb.append(asAPI ? ".gridGapX(\"" : ",gapx ").append(getBS(gridGapX));
- } else if (gridGapY != null) {
- sb.append(asAPI ? ".gridGapY(\"" : ",gapy ").append(getBS(gridGapY));
- }
- if (asAPI)
- sb.append("\")");
- }
-
- int wrapAfter = lc.getWrapAfter();
- if (wrapAfter != LayoutUtil.INF) {
- String ws = wrapAfter > 0 ? String.valueOf(wrapAfter) : "";
- if (asAPI) {
- sb.append(".wrap(").append(ws).append(')');
- } else {
- sb.append(",wrap ").append(ws);
- }
- }
-
- int debugMillis = lc.getDebugMillis();
- if (debugMillis > 0) {
- if (asAPI) {
- sb.append(".debug(").append(debugMillis).append(')');
- } else {
- sb.append(",debug ").append(debugMillis);
- }
- }
-
- String s = sb.toString();
- return s.length() == 0 || s.charAt(0) != ',' ? s : s.substring(1);
- }
-
- private static String getUV(UnitValue uv)
- {
- return uv != null ? uv.getConstraintString() : "null";
- }
-
- private static String getBS(BoundSize bs)
- {
- return bs != null ? bs.getConstraintString() : "null";
- }
-}
+package net.miginfocom.layout; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** This class contains static methods to be used by IDE vendors to convert to and from String/API constraints. + * <p> + * <b>Note that {@link LayoutUtil#setDesignTime(boolean)} should be set to <code>true</code> for this class' + * methods to work.</b> + */ +public class IDEUtil +{ + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue ZERO = UnitValue.ZERO; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue TOP = UnitValue.TOP; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue LEADING = UnitValue.LEADING; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue LEFT = UnitValue.LEFT; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue CENTER = UnitValue.CENTER; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue TRAILING = UnitValue.TRAILING; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue RIGHT = UnitValue.RIGHT; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue BOTTOM = UnitValue.BOTTOM; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue LABEL = UnitValue.LABEL; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue INF = UnitValue.INF; + + /** A direct reference to the corresponding value for predefined UnitValues in {@link UnitValue}. + */ + public static final UnitValue BASELINE_IDENTITY = UnitValue.BASELINE_IDENTITY; + + private final static String[] X_Y_STRINGS = new String[] {"x", "y", "x2", "y2"}; + + /** Returns the sizes of the rows and gaps for a container. * There will be two arrays returned [0] and [1]. + * <p> + * The first array will be the indexes of the rows where indexes that + * are less than 30000 or larger than 30000 is docking rows. There might be extra docking rows that aren't + * visible but they always have size 0. Non docking indexes will probably always be 0, 1, 2, 3, etc.. + * <p> + * The second array is the sizes of the form:<br> + * <code>[left inset][row size 1][gap 1][row size 2][gap 2][row size n][right inset]</code>. + * <p> + * The returned sizes will be the ones calculated in the last layout cycle. + * @param parentContainer The container to retuern the row sizes and gaps for. In Swing it will be a {@link java.awt.Container} and + * in SWT it will be a {@link org.eclipse.swt.widgets.Composite}. + * @return The sizes or <code>null</code> if {@link LayoutUtil#isDesignTime()} is <code>false</code> or + * <code>parentContainer</code> does not have a MigLayout layout manager. + * The returned sizes will be the ones calculated in the last layout cycle. + * @see LayoutUtil#isDesignTime() + */ + public static int[][] getRowSizes(Object parentContainer) + { + return Grid.getSizesAndIndexes(parentContainer, true); + } + + /** Returns the sizes of the columns and gaps for a container. + * There will be two arrays returned [0] and [1]. + * <p> + * The first array will be the indexes of the columns where indexes that + * are less than 30000 or larger than 30000 is docking columns. There might be extra docking columns that aren't + * visible but they always have size 0. Non docking indexes will probably always be 0, 1, 2, 3, etc.. + * <p> + * The second array is the sizes of the form:<br> + * <code>[top inset][column size 1][gap 1][column size 2][gap 2][column size n][bottom inset]</code>. + * <p> + * The returned sizes will be the ones calculated in the last layout cycle. + * @param parentContainer The container to retuern the column sizes and gaps for. In Swing it will be a {@link java.awt.Container} and + * in SWT it will be a {@link org.eclipse.swt.widgets.Composite}. + * @return The sizes and indexes or <code>null</code> if {@link LayoutUtil#isDesignTime()} is <code>false</code> or + * <code>parentContainer</code> does not have a MigLayout layout manager. + * The returned sizes will be the ones calculated in the last layout cycle. + * @see LayoutUtil#isDesignTime() + */ + public static int[][] getColumnSizes(Object parentContainer) + { + return Grid.getSizesAndIndexes(parentContainer, false); + } + + /** Returns the a constraint string that can be re-parsed to be the exact same AxisConstraint. + * @param ac The axis constraint to return as a constraint string. + * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or + * as a String type (e.g. "flowx, gap rel, right"). + * @param isCols The the constraint should be returned for columns rather than rows. + * @return A String. Never <code>null</code>. + */ + public static final String getConstraintString(AC ac, boolean asAPI, boolean isCols) + { + StringBuffer sb = new StringBuffer(32); + + DimConstraint[] dims = ac.getConstaints(); + BoundSize defGap = isCols ? PlatformDefaults.getGridGapX() : PlatformDefaults.getGridGapY(); + + for (int i = 0; i < dims.length; i++) { + DimConstraint dc = dims[i]; + + addRowDimConstraintString(dc, sb, asAPI); + + if (i < dims.length - 1) { + BoundSize gapAft = dc.getGapAfter(); + BoundSize gapBefNext = dims[i + 1].getGapBefore(); + + if (gapAft != null && gapAft == gapBefNext && gapAft != defGap) { + if (asAPI) { + sb.append(".gap(\"").append(getBS(gapAft)).append("\")"); + } else { + sb.append(getBS(gapAft)); + } + } else { + if (asAPI) + sb.append(".gap()"); + } + } + } + + return sb.toString(); + } + + /** Adds the a constraint string that can be re-parsed to be the exact same DimConstraint. + * @param dc The layout constraint to return as a constraint string. + * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or + * as a String type (e.g. "flowx, gap rel, right"). + */ + private static final void addRowDimConstraintString(DimConstraint dc, StringBuffer sb, boolean asAPI) + { + int gp = dc.getGrowPriority(); + + int firstComma = sb.length(); + + BoundSize size = dc.getSize(); + if (size != null) { + if (asAPI) { + sb.append(".size(\"").append(getBS(size)).append("\")"); + } else { + sb.append(',').append(getBS(size)); + } + } + + if (gp != 100) { + if (asAPI) { + sb.append(".growPrio(").append(gp).append("\")"); + } else { + sb.append(",growprio ").append(gp); + } + } + + Float gw = dc.getGrow(); + if (gw != null) { + String g = gw.floatValue() != 100f ? LayoutUtil.floatToString(gw.floatValue()) : ""; + if (asAPI) { + if (g.length() == 0) { + sb.append(".grow()"); + } else { + sb.append(".grow(\"").append(g).append("\")"); + } + } else { + sb.append(",grow").append(g.length() > 0 ? (" " + g) : ""); + } + } + + int sp = dc.getShrinkPriority(); + if (sp != 100) { + if (asAPI) { + sb.append(".shrinkPrio(").append(sp).append("\")"); + } else { + sb.append(",shrinkprio ").append(sp); + } + } + + Float sw = dc.getShrink(); + if (sw != null && sw.intValue() != 100) { + String s = LayoutUtil.floatToString(sw.floatValue()); + if (asAPI) { + sb.append(".shrink(\"").append(s).append("\")"); + } else { + sb.append(",shrink ").append(s); + } + } + + String eg = dc.getEndGroup(); + if (eg != null) { + if (asAPI) { + sb.append(".endGroup(\"").append(eg).append("\")"); + } else { + sb.append(",endgroup ").append(eg); + } + } + + String sg = dc.getSizeGroup(); + if (sg != null) { + if (asAPI) { + sb.append(".sizeGroup(\"").append(sg).append("\")"); + } else { + sb.append(",sizegroup ").append(sg); + } + } + + UnitValue al = dc.getAlign(); + if (al != null) { + if (asAPI) { + sb.append(".align(\"").append(getUV(al)).append("\")"); + } else { + String s = getUV(al); + String alKw = (s.equals("top") || s.equals("bottom") || s.equals("left") || s.equals("label") || + s.equals("leading") || s.equals("center") || s.equals("trailing") || + s.equals("right") || s.equals("baseline")) ? "" : "align "; + sb.append(',').append(alKw).append(s); + } + } + + if (dc.isNoGrid()) { + if (asAPI) { + sb.append(".noGrid()"); + } else { + sb.append(",nogrid"); + } + } + + if (dc.isFill()) { + if (asAPI) { + sb.append(".fill()"); + } else { + sb.append(",fill"); + } + } + + if (asAPI == false) { + if (sb.length() > firstComma) { + sb.setCharAt(firstComma, '['); + sb.append(']'); + } else { + sb.append("[]"); + } + } + } + + /** Returns the a constraint string that can be re-parsed to be the exact same DimConstraint. + * @param dc The layout constraint to return as a constraint string. + * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or + * as a String type (e.g. "flowx, gap rel, right"). + * @param isHor The the DimConstraint is decoration something horizontal (column or x). + * @param noGrowAdd If <code>true</code> no grow constraints will be added. + * @return A constraint string. Never <code>null</code>. + */ + private static final void addComponentDimConstraintString(DimConstraint dc, StringBuffer sb, boolean asAPI, boolean isHor, boolean noGrowAdd) + { + int gp = dc.getGrowPriority(); + if (gp != 100) { + if (asAPI) { + sb.append(isHor ? ".growPrioX(" : ".growPrioY(").append(gp).append(')'); + } else { + sb.append(isHor ? ",growpriox " : ",growprioy ").append(gp); + } + } + + if (noGrowAdd == false) { + Float gw = dc.getGrow(); + if (gw != null) { + String g = gw.floatValue() != 100f ? LayoutUtil.floatToString(gw.floatValue()) : ""; + if (asAPI) { + sb.append(isHor ? ".growX(" : ".growY(").append(g).append(')'); + } else { + sb.append(isHor ? ",growx" : ",growy").append(g.length() > 0 ? (" " + g) : ""); + } + } + } + + int sp = dc.getShrinkPriority(); + if (sp != 100) { + if (asAPI) { + sb.append(isHor ? ".shrinkPrioX(" : ".shrinkPrioY(").append(sp).append(')'); + } else { + sb.append(isHor ? ",shrinkpriox " : ",shrinkprioy ").append(sp); + } + } + + Float sw = dc.getShrink(); + if (sw != null && sw.intValue() != 100) { + String s = LayoutUtil.floatToString(sw.floatValue()); + if (asAPI) { + sb.append(isHor ? ".shrinkX(" : ".shrinkY(").append(s).append(')'); + } else { + sb.append(isHor ? ",shrinkx " : ",shrinky ").append(s); + } + } + + String eg = dc.getEndGroup(); + if (eg != null) { + if (asAPI) { + sb.append(isHor ? ".endGroupX(\"" : ".endGroupY(\"").append(eg).append("\")"); + } else { + sb.append(isHor ? ",endgroupx " : ",endgroupy ").append(eg); + } + } + + String sg = dc.getSizeGroup(); + if (sg != null) { + if (asAPI) { + sb.append(isHor ? ".sizeGroupX(\"" : ".sizeGroupY(\"").append(sg).append("\")"); + } else { + sb.append(isHor ? ",sizegroupx " : ",sizegroupy ").append(sg); + } + } + + BoundSize size = dc.getSize(); + if (size != null) { + if (size.getPreferred() == null) { + if (size.getMin() == null) { + if (asAPI) { + sb.append(isHor ? ".maxWidth(\"" : ".maxHeight(\"").append(getBS(size)).append("\")"); + } else { + sb.append(isHor ? ",wmax " : ",hmax ").append(getBS(size)); + } + + } else if (size.getMax() == null) { + if (asAPI) { + sb.append(isHor ? ".minWidth(\"" : ".minHeight(\"").append(getBS(size)).append("\")"); + } else { + sb.append(isHor ? ",wmin " : ",hmin ").append(getBS(size)); + } + } + } else { + if (asAPI) { + sb.append(isHor ? ".width(\"" : ".height(\"").append(getBS(size)).append("\")"); + } else { + sb.append(isHor ? ",width " : ",height ").append(getBS(size)); + } + } + } + + UnitValue al = dc.getAlign(); + if (al != null) { + if (asAPI) { + sb.append(isHor ? ".alignX(\"" : ".alignY(\"").append(getUV(al)).append("\")"); + } else { + sb.append(isHor ? ",alignx " : ",aligny ").append(getUV(al)); + } + } + + BoundSize gapBef = dc.getGapBefore(); + BoundSize gapAft= dc.getGapAfter(); + if (gapBef != null || gapAft != null) { + if (asAPI) { + sb.append(isHor ? ".gapX(\"" : ".gapY(\"").append(getBS(gapBef)).append("\", \"").append(getBS(gapAft)).append("\")"); + } else { + sb.append(isHor ? ",gapx " : ",gapy ").append(getBS(gapBef)).append(' ').append(getBS(gapAft)); + } + } + } + + /** Returns the a constraint string that can be re-parsed to be the exact same LayoutConstraint. + * @param cc The component constraint to return as a constraint string. + * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or + * as a String type (e.g. "flowx, gap rel, right"). + * @return A String. Never <code>null</code>. + */ + public static final String getConstraintString(CC cc, boolean asAPI) + { + StringBuffer sb = new StringBuffer(16); + + if (cc.isNewline()) + sb.append(asAPI ? ".newline()" : ",newline"); + + if (cc.isExternal()) + sb.append(asAPI ? ".external()" : ",external"); + + Boolean flowX = cc.getFlowX(); + if (flowX != null) { + if (asAPI) { + sb.append(flowX.booleanValue() ? ".flowX()" : ".flowY()"); + } else { + sb.append(flowX.booleanValue() ? ",flowx" : ",flowy"); + } + } + + UnitValue[] pad = cc.getPadding(); + if (pad != null) { + sb.append(asAPI ? ".pad(\"" : ",pad "); + for (int i = 0; i < pad.length; i++) + sb.append(getUV(pad[i])).append(i < pad.length - 1 ? " " : ""); + if (asAPI) + sb.append("\")"); + } + + UnitValue[] pos = cc.getPos(); + if (pos != null) { + if (cc.isBoundsInGrid()) { + for (int i = 0; i < 4; i++) { + if (pos[i] != null) { + if (asAPI) { + sb.append('.').append(X_Y_STRINGS[i]).append("(\"").append(getUV(pos[i])).append("\")"); + } else { + sb.append(',').append(X_Y_STRINGS[i]).append(getUV(pos[i])); + } + } + } + } else { + sb.append(asAPI ? ".pos(\"" : ",pos "); + int iSz = (pos[2] != null || pos[3] != null) ? 4 : 2; // "pos x y" vs "pos x1 y1 x2 y2". + for (int i = 0; i < iSz; i++) + sb.append(getUV(pos[i])).append(i < iSz - 1 ? " " : ""); + + if (asAPI) + sb.append("\")"); + } + } + + String id = cc.getId(); + if (id != null) { + if (asAPI) { + sb.append(".id(\"").append(id).append("\")"); + } else { + sb.append(",id ").append(id); + } + } + + String tag = cc.getTag(); + if (tag != null) { + if (asAPI) { + sb.append(".tag(\"").append(tag).append("\")"); + } else { + sb.append(",tag ").append(tag); + } + } + + int hideMode = cc.getHideMode(); + if (hideMode >= 0) { + if (asAPI) { + sb.append(".hideMode(").append(hideMode).append(')'); + } else { + sb.append(",hideMode ").append(hideMode); + } + } + + int skip = cc.getSkip(); + if (skip > 0) { + if (asAPI) { + sb.append(".skip(").append(skip).append(')'); + } else { + sb.append(",skip ").append(skip); + } + } + + int split = cc.getSplit(); + if (split > 1) { + String s = split == LayoutUtil.INF ? "" : String.valueOf(split); + if (asAPI) { + sb.append(".split(").append(s).append(')'); + } else { + sb.append(",split ").append(s); + } + } + + int cx = cc.getCellX(); + int cy = cc.getCellY(); + int spanX = cc.getSpanX(); + int spanY = cc.getSpanY(); + if (cx >= 0 && cy >= 0) { + if (asAPI) { + sb.append(".cell(").append(cx).append(", ").append(cy); + if (spanX > 1 || spanY > 1) + sb.append(", ").append(spanX).append(", ").append(spanY); + sb.append(')'); + } else { + sb.append(",cell ").append(cx).append(' ').append(cy); + if (spanX > 1 || spanY > 1) + sb.append(' ').append(spanX).append(' ').append(spanY); + } + } else if (spanX > 1 || spanY > 1) { + if (spanX > 1 && spanY > 1) { + sb.append(asAPI ? ".span(" : ",span ").append(spanX).append(asAPI ? ", " : " ").append(spanY); + } else if (spanX > 1) { + sb.append(asAPI ? ".spanX(" : ",spanx ").append(spanX == LayoutUtil.INF ? "" : (String.valueOf(spanX))); + } else if (spanY > 1) { + sb.append(asAPI ? ".spanY(" : ",spany ").append(spanY == LayoutUtil.INF ? "" : (String.valueOf(spanY))); + } + if (asAPI) + sb.append(')'); + } + + Float pushX = cc.getPushX(); + Float pushY = cc.getPushY(); + if (pushX != null || pushY != null) { + if (pushX != null && pushY != null) { + sb.append(asAPI ? ".push(" : ",push "); + if (pushX != 100.0 || pushY != 100.0) + sb.append(pushX).append(asAPI ? ", " : " ").append(pushY); + } else if (pushX != null) { + sb.append(asAPI ? ".pushX(" : ",pushx ").append(pushX == 100 ? "" : (String.valueOf(pushX))); + } else if (pushY != null) { + sb.append(asAPI ? ".pushY(" : ",pushy ").append(pushY == 100 ? "" : (String.valueOf(pushY))); + } + if (asAPI) + sb.append(')'); + } + + int dock = cc.getDockSide(); + if (dock >= 0) { + String ds = CC.DOCK_SIDES[dock]; + if (asAPI) { + sb.append(".dock").append(Character.toUpperCase(ds.charAt(0))).append(ds.substring(1)).append("()"); + } else { + sb.append(",").append(ds); + } + } + + boolean noGrowAdd = cc.getHorizontal().getGrow() != null && cc.getHorizontal().getGrow().intValue() == 100 && + cc.getVertical().getGrow() != null && cc.getVertical().getGrow().intValue() == 100; + + addComponentDimConstraintString(cc.getHorizontal(), sb, asAPI, true, noGrowAdd); + addComponentDimConstraintString(cc.getVertical(), sb, asAPI, false, noGrowAdd); + if (noGrowAdd) + sb.append(asAPI ? ".grow()" : ",grow"); // Combine ".growX().growY()" into ".grow()". + + if (cc.isWrap()) + sb.append(asAPI ? ".wrap()" : ",wrap"); + + String s = sb.toString(); + return s.length() == 0 || s.charAt(0) != ',' ? s : s.substring(1); + } + + /** Returns the a constraint string that can be re-parsed to be the exact same LayoutConstraint. + * @param lc The layout constraint to return as a constraint string. + * @param asAPI If the returned string should be of API type (e.g. .flowX().gap("rel").align("right")) or + * as a String type (e.g. "flowx, gap rel, right"). + * @return A String. Never <code>null</code>. + */ + public static final String getConstraintString(LC lc, boolean asAPI) + { + StringBuffer sb = new StringBuffer(16); + + if (lc.isFlowX() == false) + sb.append(asAPI ? ".flowY()" : ",flowy"); + + boolean fillX = lc.isFillX(); + boolean fillY = lc.isFillY(); + if (fillX || fillY) { + if (fillX == fillY) { + sb.append(asAPI ? ".fill()" : ",fill"); + } else { + sb.append(asAPI ? (fillX ? ".fillX()" : ".fillY()") : (fillX ? ",fillx" : ",filly")); + } + } + + Boolean leftToRight = lc.getLeftToRight(); + if (leftToRight != null) { + if (asAPI) { + sb.append(".leftToRight(").append(leftToRight).append(')'); + } else { + sb.append(leftToRight.booleanValue() ? ",ltr" : ",rtl"); + } + } + + if (lc.isTopToBottom() == false) + sb.append(asAPI ? ".bottomToTop()" : ",btt"); + + UnitValue[] insets = lc.getInsets(); + if (insets != null) { + String cs = LayoutUtil.getCCString(insets); + if (cs != null) { + if (asAPI) { + sb.append(".insets(\"").append(cs).append("\")"); + } else { + sb.append(",insets ").append(cs); + } + } else { + sb.append(asAPI ? ".insets(\"" : ",insets "); + for (int i = 0; i < insets.length; i++) + sb.append(getUV(insets[i])).append(i < insets.length - 1 ? " " : ""); + if (asAPI) + sb.append("\")"); + } + } + + if (lc.isNoGrid()) + sb.append(asAPI ? ".noGrid()" : ",nogrid"); + + if (lc.isVisualPadding() == false) + sb.append(asAPI ? ".noVisualPadding()" : ",novisualpadding"); + + int hideMode = lc.getHideMode(); + if (hideMode > 0) { + if (asAPI) { + sb.append(".hideMode(").append(hideMode).append(')'); + } else { + sb.append(",hideMode ").append(hideMode); + } + } + + UnitValue alignX = lc.getAlignX(); + UnitValue alignY = lc.getAlignY(); + if (alignX != null || alignY != null) { + if (alignX != null && alignY != null) { + sb.append(asAPI ? ".align(\"" : ",align ").append(getUV(alignX)).append(' ').append(getUV(alignY)); + } else if (alignX != null) { + sb.append(asAPI ? ".alignX(\"" : ",alignx ").append(getUV(alignX)); + } else if (alignY != null) { + sb.append(asAPI ? ".alignY(\"" : ",aligny ").append(getUV(alignY)); + } + if (asAPI) + sb.append("\")"); + } + + BoundSize gridGapX = lc.getGridGapX(); + BoundSize gridGapY = lc.getGridGapY(); + if (gridGapX != null || gridGapY != null) { + if (gridGapX != null && gridGapY != null) { + sb.append(asAPI ? ".gridGap(\"" : ",gap ").append(getBS(gridGapX)).append(' ').append(getBS(gridGapY)); + } else if (gridGapX != null) { + sb.append(asAPI ? ".gridGapX(\"" : ",gapx ").append(getBS(gridGapX)); + } else if (gridGapY != null) { + sb.append(asAPI ? ".gridGapY(\"" : ",gapy ").append(getBS(gridGapY)); + } + if (asAPI) + sb.append("\")"); + } + + int wrapAfter = lc.getWrapAfter(); + if (wrapAfter != LayoutUtil.INF) { + String ws = wrapAfter > 0 ? String.valueOf(wrapAfter) : ""; + if (asAPI) { + sb.append(".wrap(").append(ws).append(')'); + } else { + sb.append(",wrap ").append(ws); + } + } + + int debugMillis = lc.getDebugMillis(); + if (debugMillis > 0) { + if (asAPI) { + sb.append(".debug(").append(debugMillis).append(')'); + } else { + sb.append(",debug ").append(debugMillis); + } + } + + String s = sb.toString(); + return s.length() == 0 || s.charAt(0) != ',' ? s : s.substring(1); + } + + private static String getUV(UnitValue uv) + { + return uv != null ? uv.getConstraintString() : "null"; + } + + private static String getBS(BoundSize bs) + { + return bs != null ? bs.getConstraintString() : "null"; + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/InCellGapProvider.java b/prototypes/miglayout/net/miginfocom/layout/InCellGapProvider.java index 96367bc1..14fd03c1 100644 --- a/prototypes/miglayout/net/miginfocom/layout/InCellGapProvider.java +++ b/prototypes/miglayout/net/miginfocom/layout/InCellGapProvider.java @@ -1,31 +1,31 @@ -package net.miginfocom.layout;
-
-/** An interfance to implement if you want to decide the gaps between two types of components within the same cell.
- * <p>
- * E.g.:
- *
- * <pre>
- * if (adjacentComp == null || adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.TOP)
- * return null;
- *
- * boolean isHor = (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT);
- *
- * if (adjacentComp.getComponetType(false) == ComponentWrapper.TYPE_LABEL && comp.getComponetType(false) == ComponentWrapper.TYPE_TEXT_FIELD)
- * return isHor ? UNRELATED_Y : UNRELATED_Y;
- *
- * return (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT) ? RELATED_X : RELATED_Y;
- * </pre
- */
-public interface InCellGapProvider
-{
- /** Returns the default gap between two components that <b>are in the same cell</b>.
- * @param comp The component that the gap is for. Never <code>null</code>.
- * @param adjacentComp The adjacent component if any. May be <code>null</code>.
- * @param adjacentSide What side the <code>adjacentComp</code> is on. {@link javax.swing.SwingUtilities#TOP} or
- * {@link javax.swing.SwingUtilities#LEFT} or {@link javax.swing.SwingUtilities#BOTTOM} or {@link javax.swing.SwingUtilities#RIGHT}.
- * @param tag The tag string that the component might be tagged with in the component constraints. May be <code>null</code>.
- * @param isLTR If it is left-to-right.
- * @return The default gap between two components or <code>null</code> if there should be no gap.
- */
- public abstract BoundSize getDefaultGap(ComponentWrapper comp, ComponentWrapper adjacentComp, int adjacentSide, String tag, boolean isLTR);
-}
+package net.miginfocom.layout; + +/** An interfance to implement if you want to decide the gaps between two types of components within the same cell. + * <p> + * E.g.: + * + * <pre> + * if (adjacentComp == null || adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.TOP) + * return null; + * + * boolean isHor = (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT); + * + * if (adjacentComp.getComponetType(false) == ComponentWrapper.TYPE_LABEL && comp.getComponetType(false) == ComponentWrapper.TYPE_TEXT_FIELD) + * return isHor ? UNRELATED_Y : UNRELATED_Y; + * + * return (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT) ? RELATED_X : RELATED_Y; + * </pre + */ +public interface InCellGapProvider +{ + /** Returns the default gap between two components that <b>are in the same cell</b>. + * @param comp The component that the gap is for. Never <code>null</code>. + * @param adjacentComp The adjacent component if any. May be <code>null</code>. + * @param adjacentSide What side the <code>adjacentComp</code> is on. {@link javax.swing.SwingUtilities#TOP} or + * {@link javax.swing.SwingUtilities#LEFT} or {@link javax.swing.SwingUtilities#BOTTOM} or {@link javax.swing.SwingUtilities#RIGHT}. + * @param tag The tag string that the component might be tagged with in the component constraints. May be <code>null</code>. + * @param isLTR If it is left-to-right. + * @return The default gap between two components or <code>null</code> if there should be no gap. + */ + public abstract BoundSize getDefaultGap(ComponentWrapper comp, ComponentWrapper adjacentComp, int adjacentSide, String tag, boolean isLTR); +} diff --git a/prototypes/miglayout/net/miginfocom/layout/LC.java b/prototypes/miglayout/net/miginfocom/layout/LC.java index 82d33191..1c9f7a8c 100644 --- a/prototypes/miglayout/net/miginfocom/layout/LC.java +++ b/prototypes/miglayout/net/miginfocom/layout/LC.java @@ -1,717 +1,717 @@ -package net.miginfocom.layout;
-
-import java.io.*;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** Contains the constraints for an instance of the {@link LC} layout manager.
- */
-public final class LC implements Externalizable
-{
- // See the corresponding set/get method for documentation of the property!
-
- private int wrapAfter = LayoutUtil.INF;
-
- private Boolean leftToRight = null;
-
- private UnitValue[] insets = null; // Never null elememts but if unset array is null
-
- private UnitValue alignX = null, alignY = null;
-
- private BoundSize gridGapX = null, gridGapY = null;
-
- private int debugMillis = 0;
-
- private int hideMode = 0;
-
- private boolean noCache = false;
-
- private boolean flowX = true;
-
- private boolean fillX = false, fillY = false;
-
- private boolean topToBottom = true;
-
- private boolean noGrid = false;
-
- private boolean visualPadding = true;
-
- /** Empty constructor.
- */
- public LC()
- {
- }
-
- // ************************************************************************
- // * JavaBean get/set methods.
- // ************************************************************************
-
-
- /** If components have sizes or positions linked to the bounds of the parent in some way (as for instance the <code>"%"</code> unit has) the cache
- * must be turned off for the panel. If components does not get the correct or expected size or position try to set this property to <code>true</code>.
- * @return <code>true</code> means no cache and slightly slower layout.
- */
- public boolean isNoCache()
- {
- return noCache;
- }
-
- /** If components have sizes or positions linked to the bounds of the parent in some way (as for instance the <code>"%"</code> unit has) the cache
- * must be turned off for the panel. If components does not get the correct or expected size or position try to set this property to <code>true</code>.
- * @param b <code>true</code> means no cache and slightly slower layout.
- */
- public void setNoCache(boolean b)
- {
- this.noCache = b;
- }
-
- /** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components
- * in the parent. <code>null</code> is default and that means top/left alignment. The relative distances between the components will not be affected
- * by this property.
- * @return The current alignment.
- */
- public final UnitValue getAlignX()
- {
- return alignX;
- }
-
- /** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components
- * in the parent. <code>null</code> is default and that means top/left alignment. The relative distances between the components will not be affected
- * by this property.
- * @param uv The new alignment. Use {@link ConstraintParser#parseAlignKeywords(String, boolean)} to create the {@link UnitValue}. May be <code>null</code>.
- */
- public final void setAlignX(UnitValue uv)
- {
- this.alignX = uv;
- }
-
- /** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components
- * in the parent. <code>null</code> is default and that means top/left alignment. The relative distances between the components will not be affected
- * by this property.
- * @return The current alignment.
- */
- public final UnitValue getAlignY()
- {
- return alignY;
- }
-
- /** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components
- * in the parent. <code>null</code> is default and that means top/left alignment. The relative distances between the components will not be affected
- * by this property.
- * @param uv The new alignment. Use {@link ConstraintParser#parseAlignKeywords(String, boolean)} to create the {@link UnitValue}. May be <code>null</code>.
- */
- public final void setAlignY(UnitValue uv)
- {
- this.alignY = uv;
- }
-
- /** If <code>> 0</code> the debug decorations will be repainted every <code>millis</code>. No debug information if <code><= 0</code> (default).
- * @return The current debug repaint interval.
- */
- public final int getDebugMillis()
- {
- return debugMillis;
- }
-
- /** If <code>> 0</code> the debug decorations will be repainted every <code>millis</code>. No debug information if <code><= 0</code> (default).
- * @param millis The new debug repaint interval.
- */
- public final void setDebugMillis(int millis)
- {
- this.debugMillis = millis;
- }
-
- /** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller.
- * @return <code>true</code> means fill. <code>false</code> is default.
- */
- public final boolean isFillX()
- {
- return fillX;
- }
-
- /** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller.
- * @param b <code>true</code> means fill. <code>false</code> is default.
- */
- public final void setFillX(boolean b)
- {
- this.fillX = b;
- }
-
- /** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller.
- * @return <code>true</code> means fill. <code>false</code> is default.
- */
- public final boolean isFillY()
- {
- return fillY;
- }
-
- /** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller.
- * @param b <code>true</code> means fill. <code>false</code> is default.
- */
- public final void setFillY(boolean b)
- {
- this.fillY = b;
- }
-
- /** The default flow direction. Normally (which is <code>true</code>) this is horizontal and that means that the "next" component
- * will be put in the cell to the right (or to the left if left-to-right is false).
- * @return <code>true</code> is the default flow horizontally.
- * @see #setLeftToRight(Boolean)
- */
- public final boolean isFlowX()
- {
- return flowX;
- }
-
- /** The default flow direction. Normally (which is <code>true</code>) this is horizontal and that means that the "next" component
- * will be put in the cell to the right (or to the left if left-to-right is false).
- * @param b <code>true</code> is the default flow horizontally.
- * @see #setLeftToRight(Boolean)
- */
- public final void setFlowX(boolean b)
- {
- this.flowX = b;
- }
-
- /** If non-<code>null</code> (<code>null</code> is default) these value will be used as the default gaps between the columns in the grid.
- * @return The default grid gap between columns in the grid. <code>null</code> if the platform default is used.
- */
- public final BoundSize getGridGapX()
- {
- return gridGapX;
- }
-
- /** If non-<code>null</code> (<code>null</code> is default) these value will be used as the default gaps between the columns in the grid.
- * @param x The default grid gap between columns in the grid. If <code>null</code> the platform default is used.
- */
- public final void setGridGapX(BoundSize x)
- {
- this.gridGapX = x;
- }
-
- /** If non-<code>null</code> (<code>null</code> is default) these value will be used as the default gaps between the rows in the grid.
- * @return The default grid gap between rows in the grid. <code>null</code> if the platform default is used.
- */
- public final BoundSize getGridGapY()
- {
- return gridGapY;
- }
-
- /** If non-<code>null</code> (<code>null</code> is default) these value will be used as the default gaps between the rows in the grid.
- * @param y The default grid gap between rows in the grid. If <code>null</code> the platform default is used.
- */
- public final void setGridGapY(BoundSize y)
- {
- this.gridGapY = y;
- }
-
- /** How a component that is hidden (not visible) should be treated by default.
- * @return The mode:<br>
- * 0 == Normal. Bounds will be caclulated as if the component was visible.<br>
- * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
- * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
- * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
- */
- public final int getHideMode()
- {
- return hideMode;
- }
-
- /** How a component that is hidden (not visible) should be treated.
- * @param mode The mode:<br>
- * 0 == Normal. Bounds will be caclulated as if the component was visible.<br>
- * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
- * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
- * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
- */
- public final void setHideMode(int mode)
- {
- if (mode < 0 || mode > 3)
- throw new IllegalArgumentException("Wrong hideMode: " + mode);
-
- this.hideMode = mode;
- }
-
- /** The insets for the layed out panel. The insets will be an empty space around the components in the panel. <code>null</code> values
- * means that the default panel insets for the platform is used. See {@link PlatformDefaults#setDialogInsets(net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue)}.
- * @return The insets. Of length 4 (top, left, bottom, right) or <code>null</code>. The elements (1 to 4) may be <code>null</code>. The array is a copy and can be used freely.
- * @see net.miginfocom.layout.ConstraintParser#parseInsets(String, boolean)
- */
- public final UnitValue[] getInsets()
- {
- return insets != null ? new UnitValue[] {insets[0], insets[1], insets[2], insets[3]} : null;
- }
-
- /** The insets for the layed out panel. The insets will be an empty space around the components in the panel. <code>null</code> values
- * means that the default panel insets for the platform is used. See {@link PlatformDefaults#setDialogInsets(net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue)}.
- * @param ins The new insets. Must be of length 4 (top, left, bottom, right) or <code>null</code>. The elements (1 to 4) may be <code>null</code> to use
- * the platform default for that side. The array is copied for storage.
- * @see net.miginfocom.layout.ConstraintParser#parseInsets(String, boolean)
- */
- public final void setInsets(UnitValue[] ins)
- {
- this.insets = ins != null ? new UnitValue[] {ins[0], ins[1], ins[2], ins[3]} : null;
- }
-
- /** If the layout should be forced to be left-to-right or right-to-left. A value of <code>null</code> is default and
- * means that this will be picked up from the {@link java.util.Locale} that the container being layed out is reporting.
- * @return <code>Boolean.TRUE</code> if force left-to-right. <code>Boolean.FALSE</code> if force tight-to-left. <code>null</code>
- * for the default "let the current Locale decide".
- */
- public final Boolean getLeftToRight()
- {
- return leftToRight;
- }
-
- /** If the layout should be forced to be left-to-right or right-to-left. A value of <code>null</code> is default and
- * means that this will be picked up from the {@link java.util.Locale} that the container being layed out is reporting.
- * @param b <code>Boolean.TRUE</code> to force left-to-right. <code>Boolean.FALSE</code> to force tight-to-left. <code>null</code>
- * for the default "let the current Locale decide".
- */
- public final void setLeftToRight(Boolean b)
- {
- this.leftToRight = b;
- }
-
- /** If the whole layout should be non grid based. It is the same as setting the "nogrid" property on every row/column in the grid.
- * @return <code>true</code> means not grid based. <code>false</code> is default.
- */
- public final boolean isNoGrid()
- {
- return noGrid;
- }
-
- /** If the whole layout should be non grid based. It is the same as setting the "nogrid" property on every row/column in the grid.
- * @param b <code>true</code> means no grid. <code>false</code> is default.
- */
- public final void setNoGrid(boolean b)
- {
- this.noGrid = b;
- }
-
- /** If the layout should go from the default top-to-bottom in the grid instead of the optinal bottom-to-top.
- * @return <code>true</code> for the default top-to-bottom.
- */
- public final boolean isTopToBottom()
- {
- return topToBottom;
- }
-
- /** If the layout should go from the default top-to-bottom in the grid instead of the optinal bottom-to-top.
- * @param b <code>true</code> for the default top-to-bottom.
- */
- public final void setTopToBottom(boolean b)
- {
- this.topToBottom = b;
- }
-
- /** If visual padding should be automatically used and compensated for by this layout instance.
- * @return <code>true</code> if visual padding.
- */
- public final boolean isVisualPadding()
- {
- return visualPadding;
- }
-
- /** If visual padding should be automatically used and compensated for by this layout instance.
- * @param b <code>true</code> turns on visual padding.
- */
- public final void setVisualPadding(boolean b)
- {
- this.visualPadding = b;
- }
-
- /** Returns after what cell the grid should always auto wrap.
- * @return After what cell the grid should always auto wrap. If <code>0</code> the number of columns/rows in the
- * {@link net.miginfocom.layout.AC} is used. <code>LayoutUtil.INF</code> is used for no auto wrap.
- */
- public final int getWrapAfter()
- {
- return wrapAfter;
- }
-
- /** Sets after what cell the grid should always auto wrap.
- * @param count After what cell the grid should always auto wrap. If <code>0</code> the number of columns/rows in the
- * {@link net.miginfocom.layout.AC} is used. <code>LayoutUtil.INF</code> is used for no auto wrap.
- */
- public final void setWrapAfter(int count)
- {
- this.wrapAfter = count;
- }
-
- // ************************************************************************
- // * Builder methods.
- // ************************************************************************
-
- /** Sets a wrap after the number of columns/rows that is defined in the {@link net.miginfocom.layout.AC}.
- * <p>
- * Same functionality as {@link #setWrapAfter(int 0)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC wrap()
- {
- setWrapAfter(0);
- return this;
- }
-
- /** Same functionality as {@link #setWrapAfter(int)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param count After what cell the grid should always auto wrap. If <code>0</code> the number of columns/rows in the
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC wrapAfter(int count)
- {
- setWrapAfter(count);
- return this;
- }
-
- /** Same functionality as {@link #setNoCache(boolean true)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC noCache()
- {
- setNoCache(true);
- return this;
- }
-
- /** Same functionality as {@link #setFlowX(boolean false)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC flowY()
- {
- setFlowX(false);
- return this;
- }
-
- /** Same functionality as {@link #setFlowX(boolean true)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC flowX()
- {
- setFlowX(true);
- return this;
- }
-
- /** Same functionality as {@link #setFillX(boolean true)} and {@link #setFillY(boolean true)} conmbined.T his method returns
- * <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC fill()
- {
- setFillX(true);
- setFillY(true);
- return this;
- }
-
- /** Same functionality as {@link #setFillX(boolean true)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC fillX()
- {
- setFillX(true);
- return this;
- }
-
- /** Same functionality as {@link #setFillY(boolean true)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC fillY()
- {
- setFillY(true);
- return this;
- }
-
- /** Same functionality as {@link #setLeftToRight(Boolean)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param b <code>true</code> for forcing left-to-right. <code>false</code> for forcing right-to-left.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC leftToRight(boolean b)
- {
- setLeftToRight(b ? Boolean.TRUE : Boolean.FALSE); // Not .valueOf du to retroweaver...
- return this;
- }
-
- /** Same functionality as {@link #setTopToBottom(boolean false)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC bottomToTop()
- {
- setTopToBottom(false);
- return this;
- }
-
- /** Same functionality as {@link #setNoGrid(boolean true)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC noGrid()
- {
- setNoGrid(true);
- return this;
- }
-
- /** Same functionality as {@link #setVisualPadding(boolean false)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- */
- public final LC noVisualPadding()
- {
- setVisualPadding(false);
- return this;
- }
-
- /** Sets the same inset (expressed as a <code>UnitValue</code>, e.g. "10px" or "20mm") all around.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param allSides The unit value to set for all sides. May be <code>null</code> which means that the default panel insets
- * for the platform is used.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setInsets(UnitValue[])
- */
- public final LC insetsAll(String allSides)
- {
- UnitValue insH = ConstraintParser.parseUnitValue(allSides, true);
- UnitValue insV = ConstraintParser.parseUnitValue(allSides, false);
- insets = new UnitValue[] {insV, insH, insV, insH}; // No setter to avoid copy again
- return this;
- }
-
- /** Same functionality as <code>setInsets(ConstraintParser.parseInsets(s, true))</code>. This method returns <code>this</code>
- * for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param s The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setInsets(UnitValue[])
- */
- public final LC insets(String s)
- {
- insets = ConstraintParser.parseInsets(s, true);
- return this;
- }
-
- /** Sets the different insets (expressed as a <code>UnitValue</code>s, e.g. "10px" or "20mm") for the corresponding sides.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param top The top inset. E.g. "10px" or "10mm" or "related". May be <code>null</code> in which case the default inset for this
- * side for the platform will be used.
- * @param left The left inset. E.g. "10px" or "10mm" or "related". May be <code>null</code> in which case the default inset for this
- * side for the platform will be used.
- * @param bottom The bottom inset. E.g. "10px" or "10mm" or "related". May be <code>null</code> in which case the default inset for this
- * side for the platform will be used.
- * @param right The right inset. E.g. "10px" or "10mm" or "related". May be <code>null</code> in which case the default inset for this
- * side for the platform will be used.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setInsets(UnitValue[])
- */
- public final LC insets(String top, String left, String bottom, String right)
- {
- insets = new UnitValue[] { // No setter to avoid copy again
- ConstraintParser.parseUnitValue(top, false),
- ConstraintParser.parseUnitValue(left, true),
- ConstraintParser.parseUnitValue(bottom, false),
- ConstraintParser.parseUnitValue(right, true)};
- return this;
- }
-
- /** Same functionality as <code>setAlignX(ConstraintParser.parseUnitValueOrAlign(unitValue, true))</code> only this method returns <code>this</code>
- * for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param align The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setAlignX(UnitValue)
- */
- public final LC alignX(String align)
- {
- setAlignX(ConstraintParser.parseUnitValueOrAlign(align, true, null));
- return this;
- }
-
- /** Same functionality as <code>setAlignY(ConstraintParser.parseUnitValueOrAlign(align, false))</code> only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param align The align keyword or for instance "100px". E.g "top" or "bottom".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setAlignY(UnitValue)
- */
- public final LC alignY(String align)
- {
- setAlignY(ConstraintParser.parseUnitValueOrAlign(align, false, null));
- return this;
- }
-
- /** Sets both the alignX and alignY as the same time.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param ax The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing".
- * @param ay The align keyword or for instance "100px". E.g "top" or "bottom".
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #alignX(String)
- * @see #alignY(String)
- */
- public final LC align(String ax, String ay)
- {
- if (ax != null)
- alignX(ax);
-
- if (ay != null)
- alignY(ay);
-
- return this;
- }
-
- /** Same functionality as <code>setGridGapX(ConstraintParser.parseBoundSize(boundsSize, true, true))</code> only this method
- * returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param boundsSize The <code>BoundSize</code> of the gap. This is a minimum and/or preferred and/or maximum size. E.g.
- * <code>"50:100:200"</code> or <code>"100px"</code>.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setGridGapX(BoundSize)
- */
- public final LC gridGapX(String boundsSize)
- {
- setGridGapX(ConstraintParser.parseBoundSize(boundsSize, true, true));
- return this;
- }
-
- /** Same functionality as <code>setGridGapY(ConstraintParser.parseBoundSize(boundsSize, true, false))</code> only this method
- * returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param boundsSize The <code>BoundSize</code> of the gap. This is a minimum and/or preferred and/or maximum size. E.g.
- * <code>"50:100:200"</code> or <code>"100px"</code>.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setGridGapY(BoundSize)
- */
- public final LC gridGapY(String boundsSize)
- {
- setGridGapY(ConstraintParser.parseBoundSize(boundsSize, true, false));
- return this;
- }
-
- /** Sets both grid gaps at the same time. see {@link #gridGapX(String)} and {@link #gridGapY(String)}.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param gapx The <code>BoundSize</code> of the gap. This is a minimum and/or preferred and/or maximum size. E.g.
- * <code>"50:100:200"</code> or <code>"100px"</code>.
- * @param gapy The <code>BoundSize</code> of the gap. This is a minimum and/or preferred and/or maximum size. E.g.
- * <code>"50:100:200"</code> or <code>"100px"</code>.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #gridGapX(String)
- * @see #gridGapY(String)
- */
- public final LC gridGap(String gapx, String gapy)
- {
- if (gapx != null)
- gridGapX(gapx);
-
- if (gapy != null)
- gridGapY(gapy);
-
- return this;
- }
-
- /** Same functionality as {@link #setDebugMillis(int repaintMillis)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param repaintMillis The new debug repaint interval.
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setDebugMillis(int)
- */
- public final LC debug(int repaintMillis)
- {
- setDebugMillis(repaintMillis);
- return this;
- }
-
- /** Same functionality as {@link #setHideMode(int mode)} only this method returns <code>this</code> for chaining multiple calls.
- * <p>
- * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com.
- * @param mode The mode:<br>
- * 0 == Normal. Bounds will be caclulated as if the component was visible.<br>
- * 1 == If hidden the size will be 0, 0 but the gaps remain.<br>
- * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br>
- * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid..
- * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>.
- * @see #setHideMode(int)
- */
- public final LC hideMode(int mode)
- {
- setHideMode(mode);
- return this;
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
-
- public void writeExternal(ObjectOutput out) throws IOException
- {
- if (getClass() == LC.class)
- LayoutUtil.writeAsXML(out, this);
- }
-}
+package net.miginfocom.layout; + +import java.io.*; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** Contains the constraints for an instance of the {@link LC} layout manager. + */ +public final class LC implements Externalizable +{ + // See the corresponding set/get method for documentation of the property! + + private int wrapAfter = LayoutUtil.INF; + + private Boolean leftToRight = null; + + private UnitValue[] insets = null; // Never null elememts but if unset array is null + + private UnitValue alignX = null, alignY = null; + + private BoundSize gridGapX = null, gridGapY = null; + + private int debugMillis = 0; + + private int hideMode = 0; + + private boolean noCache = false; + + private boolean flowX = true; + + private boolean fillX = false, fillY = false; + + private boolean topToBottom = true; + + private boolean noGrid = false; + + private boolean visualPadding = true; + + /** Empty constructor. + */ + public LC() + { + } + + // ************************************************************************ + // * JavaBean get/set methods. + // ************************************************************************ + + + /** If components have sizes or positions linked to the bounds of the parent in some way (as for instance the <code>"%"</code> unit has) the cache + * must be turned off for the panel. If components does not get the correct or expected size or position try to set this property to <code>true</code>. + * @return <code>true</code> means no cache and slightly slower layout. + */ + public boolean isNoCache() + { + return noCache; + } + + /** If components have sizes or positions linked to the bounds of the parent in some way (as for instance the <code>"%"</code> unit has) the cache + * must be turned off for the panel. If components does not get the correct or expected size or position try to set this property to <code>true</code>. + * @param b <code>true</code> means no cache and slightly slower layout. + */ + public void setNoCache(boolean b) + { + this.noCache = b; + } + + /** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components + * in the parent. <code>null</code> is default and that means top/left alignment. The relative distances between the components will not be affected + * by this property. + * @return The current alignment. + */ + public final UnitValue getAlignX() + { + return alignX; + } + + /** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components + * in the parent. <code>null</code> is default and that means top/left alignment. The relative distances between the components will not be affected + * by this property. + * @param uv The new alignment. Use {@link ConstraintParser#parseAlignKeywords(String, boolean)} to create the {@link UnitValue}. May be <code>null</code>. + */ + public final void setAlignX(UnitValue uv) + { + this.alignX = uv; + } + + /** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components + * in the parent. <code>null</code> is default and that means top/left alignment. The relative distances between the components will not be affected + * by this property. + * @return The current alignment. + */ + public final UnitValue getAlignY() + { + return alignY; + } + + /** If the laid out components' bounds in total is less than the final size of the container these align values will be used to align the components + * in the parent. <code>null</code> is default and that means top/left alignment. The relative distances between the components will not be affected + * by this property. + * @param uv The new alignment. Use {@link ConstraintParser#parseAlignKeywords(String, boolean)} to create the {@link UnitValue}. May be <code>null</code>. + */ + public final void setAlignY(UnitValue uv) + { + this.alignY = uv; + } + + /** If <code>> 0</code> the debug decorations will be repainted every <code>millis</code>. No debug information if <code><= 0</code> (default). + * @return The current debug repaint interval. + */ + public final int getDebugMillis() + { + return debugMillis; + } + + /** If <code>> 0</code> the debug decorations will be repainted every <code>millis</code>. No debug information if <code><= 0</code> (default). + * @param millis The new debug repaint interval. + */ + public final void setDebugMillis(int millis) + { + this.debugMillis = millis; + } + + /** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller. + * @return <code>true</code> means fill. <code>false</code> is default. + */ + public final boolean isFillX() + { + return fillX; + } + + /** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller. + * @param b <code>true</code> means fill. <code>false</code> is default. + */ + public final void setFillX(boolean b) + { + this.fillX = b; + } + + /** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller. + * @return <code>true</code> means fill. <code>false</code> is default. + */ + public final boolean isFillY() + { + return fillY; + } + + /** If the layout should always claim the whole bounds of the laid out container even if the preferred size is smaller. + * @param b <code>true</code> means fill. <code>false</code> is default. + */ + public final void setFillY(boolean b) + { + this.fillY = b; + } + + /** The default flow direction. Normally (which is <code>true</code>) this is horizontal and that means that the "next" component + * will be put in the cell to the right (or to the left if left-to-right is false). + * @return <code>true</code> is the default flow horizontally. + * @see #setLeftToRight(Boolean) + */ + public final boolean isFlowX() + { + return flowX; + } + + /** The default flow direction. Normally (which is <code>true</code>) this is horizontal and that means that the "next" component + * will be put in the cell to the right (or to the left if left-to-right is false). + * @param b <code>true</code> is the default flow horizontally. + * @see #setLeftToRight(Boolean) + */ + public final void setFlowX(boolean b) + { + this.flowX = b; + } + + /** If non-<code>null</code> (<code>null</code> is default) these value will be used as the default gaps between the columns in the grid. + * @return The default grid gap between columns in the grid. <code>null</code> if the platform default is used. + */ + public final BoundSize getGridGapX() + { + return gridGapX; + } + + /** If non-<code>null</code> (<code>null</code> is default) these value will be used as the default gaps between the columns in the grid. + * @param x The default grid gap between columns in the grid. If <code>null</code> the platform default is used. + */ + public final void setGridGapX(BoundSize x) + { + this.gridGapX = x; + } + + /** If non-<code>null</code> (<code>null</code> is default) these value will be used as the default gaps between the rows in the grid. + * @return The default grid gap between rows in the grid. <code>null</code> if the platform default is used. + */ + public final BoundSize getGridGapY() + { + return gridGapY; + } + + /** If non-<code>null</code> (<code>null</code> is default) these value will be used as the default gaps between the rows in the grid. + * @param y The default grid gap between rows in the grid. If <code>null</code> the platform default is used. + */ + public final void setGridGapY(BoundSize y) + { + this.gridGapY = y; + } + + /** How a component that is hidden (not visible) should be treated by default. + * @return The mode:<br> + * 0 == Normal. Bounds will be caclulated as if the component was visible.<br> + * 1 == If hidden the size will be 0, 0 but the gaps remain.<br> + * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br> + * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid.. + */ + public final int getHideMode() + { + return hideMode; + } + + /** How a component that is hidden (not visible) should be treated. + * @param mode The mode:<br> + * 0 == Normal. Bounds will be caclulated as if the component was visible.<br> + * 1 == If hidden the size will be 0, 0 but the gaps remain.<br> + * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br> + * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid.. + */ + public final void setHideMode(int mode) + { + if (mode < 0 || mode > 3) + throw new IllegalArgumentException("Wrong hideMode: " + mode); + + this.hideMode = mode; + } + + /** The insets for the layed out panel. The insets will be an empty space around the components in the panel. <code>null</code> values + * means that the default panel insets for the platform is used. See {@link PlatformDefaults#setDialogInsets(net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue)}. + * @return The insets. Of length 4 (top, left, bottom, right) or <code>null</code>. The elements (1 to 4) may be <code>null</code>. The array is a copy and can be used freely. + * @see net.miginfocom.layout.ConstraintParser#parseInsets(String, boolean) + */ + public final UnitValue[] getInsets() + { + return insets != null ? new UnitValue[] {insets[0], insets[1], insets[2], insets[3]} : null; + } + + /** The insets for the layed out panel. The insets will be an empty space around the components in the panel. <code>null</code> values + * means that the default panel insets for the platform is used. See {@link PlatformDefaults#setDialogInsets(net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue, net.miginfocom.layout.UnitValue)}. + * @param ins The new insets. Must be of length 4 (top, left, bottom, right) or <code>null</code>. The elements (1 to 4) may be <code>null</code> to use + * the platform default for that side. The array is copied for storage. + * @see net.miginfocom.layout.ConstraintParser#parseInsets(String, boolean) + */ + public final void setInsets(UnitValue[] ins) + { + this.insets = ins != null ? new UnitValue[] {ins[0], ins[1], ins[2], ins[3]} : null; + } + + /** If the layout should be forced to be left-to-right or right-to-left. A value of <code>null</code> is default and + * means that this will be picked up from the {@link java.util.Locale} that the container being layed out is reporting. + * @return <code>Boolean.TRUE</code> if force left-to-right. <code>Boolean.FALSE</code> if force tight-to-left. <code>null</code> + * for the default "let the current Locale decide". + */ + public final Boolean getLeftToRight() + { + return leftToRight; + } + + /** If the layout should be forced to be left-to-right or right-to-left. A value of <code>null</code> is default and + * means that this will be picked up from the {@link java.util.Locale} that the container being layed out is reporting. + * @param b <code>Boolean.TRUE</code> to force left-to-right. <code>Boolean.FALSE</code> to force tight-to-left. <code>null</code> + * for the default "let the current Locale decide". + */ + public final void setLeftToRight(Boolean b) + { + this.leftToRight = b; + } + + /** If the whole layout should be non grid based. It is the same as setting the "nogrid" property on every row/column in the grid. + * @return <code>true</code> means not grid based. <code>false</code> is default. + */ + public final boolean isNoGrid() + { + return noGrid; + } + + /** If the whole layout should be non grid based. It is the same as setting the "nogrid" property on every row/column in the grid. + * @param b <code>true</code> means no grid. <code>false</code> is default. + */ + public final void setNoGrid(boolean b) + { + this.noGrid = b; + } + + /** If the layout should go from the default top-to-bottom in the grid instead of the optinal bottom-to-top. + * @return <code>true</code> for the default top-to-bottom. + */ + public final boolean isTopToBottom() + { + return topToBottom; + } + + /** If the layout should go from the default top-to-bottom in the grid instead of the optinal bottom-to-top. + * @param b <code>true</code> for the default top-to-bottom. + */ + public final void setTopToBottom(boolean b) + { + this.topToBottom = b; + } + + /** If visual padding should be automatically used and compensated for by this layout instance. + * @return <code>true</code> if visual padding. + */ + public final boolean isVisualPadding() + { + return visualPadding; + } + + /** If visual padding should be automatically used and compensated for by this layout instance. + * @param b <code>true</code> turns on visual padding. + */ + public final void setVisualPadding(boolean b) + { + this.visualPadding = b; + } + + /** Returns after what cell the grid should always auto wrap. + * @return After what cell the grid should always auto wrap. If <code>0</code> the number of columns/rows in the + * {@link net.miginfocom.layout.AC} is used. <code>LayoutUtil.INF</code> is used for no auto wrap. + */ + public final int getWrapAfter() + { + return wrapAfter; + } + + /** Sets after what cell the grid should always auto wrap. + * @param count After what cell the grid should always auto wrap. If <code>0</code> the number of columns/rows in the + * {@link net.miginfocom.layout.AC} is used. <code>LayoutUtil.INF</code> is used for no auto wrap. + */ + public final void setWrapAfter(int count) + { + this.wrapAfter = count; + } + + // ************************************************************************ + // * Builder methods. + // ************************************************************************ + + /** Sets a wrap after the number of columns/rows that is defined in the {@link net.miginfocom.layout.AC}. + * <p> + * Same functionality as {@link #setWrapAfter(int 0)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC wrap() + { + setWrapAfter(0); + return this; + } + + /** Same functionality as {@link #setWrapAfter(int)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param count After what cell the grid should always auto wrap. If <code>0</code> the number of columns/rows in the + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC wrapAfter(int count) + { + setWrapAfter(count); + return this; + } + + /** Same functionality as {@link #setNoCache(boolean true)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC noCache() + { + setNoCache(true); + return this; + } + + /** Same functionality as {@link #setFlowX(boolean false)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC flowY() + { + setFlowX(false); + return this; + } + + /** Same functionality as {@link #setFlowX(boolean true)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC flowX() + { + setFlowX(true); + return this; + } + + /** Same functionality as {@link #setFillX(boolean true)} and {@link #setFillY(boolean true)} conmbined.T his method returns + * <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC fill() + { + setFillX(true); + setFillY(true); + return this; + } + + /** Same functionality as {@link #setFillX(boolean true)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC fillX() + { + setFillX(true); + return this; + } + + /** Same functionality as {@link #setFillY(boolean true)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC fillY() + { + setFillY(true); + return this; + } + + /** Same functionality as {@link #setLeftToRight(Boolean)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param b <code>true</code> for forcing left-to-right. <code>false</code> for forcing right-to-left. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC leftToRight(boolean b) + { + setLeftToRight(b ? Boolean.TRUE : Boolean.FALSE); // Not .valueOf du to retroweaver... + return this; + } + + /** Same functionality as {@link #setTopToBottom(boolean false)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC bottomToTop() + { + setTopToBottom(false); + return this; + } + + /** Same functionality as {@link #setNoGrid(boolean true)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC noGrid() + { + setNoGrid(true); + return this; + } + + /** Same functionality as {@link #setVisualPadding(boolean false)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + */ + public final LC noVisualPadding() + { + setVisualPadding(false); + return this; + } + + /** Sets the same inset (expressed as a <code>UnitValue</code>, e.g. "10px" or "20mm") all around. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param allSides The unit value to set for all sides. May be <code>null</code> which means that the default panel insets + * for the platform is used. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setInsets(UnitValue[]) + */ + public final LC insetsAll(String allSides) + { + UnitValue insH = ConstraintParser.parseUnitValue(allSides, true); + UnitValue insV = ConstraintParser.parseUnitValue(allSides, false); + insets = new UnitValue[] {insV, insH, insV, insH}; // No setter to avoid copy again + return this; + } + + /** Same functionality as <code>setInsets(ConstraintParser.parseInsets(s, true))</code>. This method returns <code>this</code> + * for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param s The string to parse. E.g. "10 10 10 10" or "20". If less than 4 groups the last will be used for the missing. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setInsets(UnitValue[]) + */ + public final LC insets(String s) + { + insets = ConstraintParser.parseInsets(s, true); + return this; + } + + /** Sets the different insets (expressed as a <code>UnitValue</code>s, e.g. "10px" or "20mm") for the corresponding sides. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param top The top inset. E.g. "10px" or "10mm" or "related". May be <code>null</code> in which case the default inset for this + * side for the platform will be used. + * @param left The left inset. E.g. "10px" or "10mm" or "related". May be <code>null</code> in which case the default inset for this + * side for the platform will be used. + * @param bottom The bottom inset. E.g. "10px" or "10mm" or "related". May be <code>null</code> in which case the default inset for this + * side for the platform will be used. + * @param right The right inset. E.g. "10px" or "10mm" or "related". May be <code>null</code> in which case the default inset for this + * side for the platform will be used. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setInsets(UnitValue[]) + */ + public final LC insets(String top, String left, String bottom, String right) + { + insets = new UnitValue[] { // No setter to avoid copy again + ConstraintParser.parseUnitValue(top, false), + ConstraintParser.parseUnitValue(left, true), + ConstraintParser.parseUnitValue(bottom, false), + ConstraintParser.parseUnitValue(right, true)}; + return this; + } + + /** Same functionality as <code>setAlignX(ConstraintParser.parseUnitValueOrAlign(unitValue, true))</code> only this method returns <code>this</code> + * for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param align The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setAlignX(UnitValue) + */ + public final LC alignX(String align) + { + setAlignX(ConstraintParser.parseUnitValueOrAlign(align, true, null)); + return this; + } + + /** Same functionality as <code>setAlignY(ConstraintParser.parseUnitValueOrAlign(align, false))</code> only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param align The align keyword or for instance "100px". E.g "top" or "bottom". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setAlignY(UnitValue) + */ + public final LC alignY(String align) + { + setAlignY(ConstraintParser.parseUnitValueOrAlign(align, false, null)); + return this; + } + + /** Sets both the alignX and alignY as the same time. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param ax The align keyword or for instance "100px". E.g "left", "right", "leading" or "trailing". + * @param ay The align keyword or for instance "100px". E.g "top" or "bottom". + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #alignX(String) + * @see #alignY(String) + */ + public final LC align(String ax, String ay) + { + if (ax != null) + alignX(ax); + + if (ay != null) + alignY(ay); + + return this; + } + + /** Same functionality as <code>setGridGapX(ConstraintParser.parseBoundSize(boundsSize, true, true))</code> only this method + * returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param boundsSize The <code>BoundSize</code> of the gap. This is a minimum and/or preferred and/or maximum size. E.g. + * <code>"50:100:200"</code> or <code>"100px"</code>. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setGridGapX(BoundSize) + */ + public final LC gridGapX(String boundsSize) + { + setGridGapX(ConstraintParser.parseBoundSize(boundsSize, true, true)); + return this; + } + + /** Same functionality as <code>setGridGapY(ConstraintParser.parseBoundSize(boundsSize, true, false))</code> only this method + * returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param boundsSize The <code>BoundSize</code> of the gap. This is a minimum and/or preferred and/or maximum size. E.g. + * <code>"50:100:200"</code> or <code>"100px"</code>. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setGridGapY(BoundSize) + */ + public final LC gridGapY(String boundsSize) + { + setGridGapY(ConstraintParser.parseBoundSize(boundsSize, true, false)); + return this; + } + + /** Sets both grid gaps at the same time. see {@link #gridGapX(String)} and {@link #gridGapY(String)}. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param gapx The <code>BoundSize</code> of the gap. This is a minimum and/or preferred and/or maximum size. E.g. + * <code>"50:100:200"</code> or <code>"100px"</code>. + * @param gapy The <code>BoundSize</code> of the gap. This is a minimum and/or preferred and/or maximum size. E.g. + * <code>"50:100:200"</code> or <code>"100px"</code>. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #gridGapX(String) + * @see #gridGapY(String) + */ + public final LC gridGap(String gapx, String gapy) + { + if (gapx != null) + gridGapX(gapx); + + if (gapy != null) + gridGapY(gapy); + + return this; + } + + /** Same functionality as {@link #setDebugMillis(int repaintMillis)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param repaintMillis The new debug repaint interval. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setDebugMillis(int) + */ + public final LC debug(int repaintMillis) + { + setDebugMillis(repaintMillis); + return this; + } + + /** Same functionality as {@link #setHideMode(int mode)} only this method returns <code>this</code> for chaining multiple calls. + * <p> + * For a more thorough explanation of what this constraint does see the white paper or cheat Sheet at www.migcomponents.com. + * @param mode The mode:<br> + * 0 == Normal. Bounds will be caclulated as if the component was visible.<br> + * 1 == If hidden the size will be 0, 0 but the gaps remain.<br> + * 2 == If hidden the size will be 0, 0 and gaps set to zero.<br> + * 3 == If hidden the component will be disregarded completely and not take up a cell in the grid.. + * @return <code>this</code> so it is possible to chain calls. E.g. <code>new LayoutConstraint().noGrid().gap().fill()</code>. + * @see #setHideMode(int) + */ + public final LC hideMode(int mode) + { + setHideMode(mode); + return this; + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + if (getClass() == LC.class) + LayoutUtil.writeAsXML(out, this); + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/LayoutCallback.java b/prototypes/miglayout/net/miginfocom/layout/LayoutCallback.java index f0855701..51acc218 100644 --- a/prototypes/miglayout/net/miginfocom/layout/LayoutCallback.java +++ b/prototypes/miglayout/net/miginfocom/layout/LayoutCallback.java @@ -1,48 +1,48 @@ -package net.miginfocom.layout;
-
-import net.miginfocom.layout.UnitValue;
-import net.miginfocom.layout.ComponentWrapper;
-import net.miginfocom.layout.BoundSize;
-
-/** A class to extend if you want to provide more control over where a component is placed or the size of it.
- * <p>
- * Note! Returned arrays from this class will never be altered. This means that caching of arrays in these methods
- * is OK.
- */
-public abstract class LayoutCallback
-{
- /** Returns a position similar to the "pos" the component constraint.
- * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT).
- * <b>Should not be altered.</b>
- * @return The [x, y, x2, y2] as explained in the documentation for "pos". If <code>null</code>
- * is returned nothing is done and this is the default.
- * @see UnitValue
- * @see net.miginfocom.layout.ConstraintParser#parseUnitValue(String, boolean)
- */
- public UnitValue[] getPosition(ComponentWrapper comp)
- {
- return null;
- }
-
- /** Returns a size similar to the "width" and "height" in the component constraint.
- * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT).
- * <b>Should not be altered.</b>
- * @return The [width, height] as explained in the documentation for "width" and "height". If <code>null</code>
- * is returned nothing is done and this is the default.
- * @see net.miginfocom.layout.BoundSize
- * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean)
- */
- public BoundSize[] getSize(ComponentWrapper comp)
- {
- return null;
- }
-
- /** A last minute change of the bounds. The bound for the layout cycle has been set and you can correct there
- * after any set of rules you like.
- * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT).
- * <b>Should not be altered.</b>
- */
- public void correctBounds(ComponentWrapper comp)
- {
- }
-}
+package net.miginfocom.layout; + +import net.miginfocom.layout.UnitValue; +import net.miginfocom.layout.ComponentWrapper; +import net.miginfocom.layout.BoundSize; + +/** A class to extend if you want to provide more control over where a component is placed or the size of it. + * <p> + * Note! Returned arrays from this class will never be altered. This means that caching of arrays in these methods + * is OK. + */ +public abstract class LayoutCallback +{ + /** Returns a position similar to the "pos" the component constraint. + * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT). + * <b>Should not be altered.</b> + * @return The [x, y, x2, y2] as explained in the documentation for "pos". If <code>null</code> + * is returned nothing is done and this is the default. + * @see UnitValue + * @see net.miginfocom.layout.ConstraintParser#parseUnitValue(String, boolean) + */ + public UnitValue[] getPosition(ComponentWrapper comp) + { + return null; + } + + /** Returns a size similar to the "width" and "height" in the component constraint. + * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT). + * <b>Should not be altered.</b> + * @return The [width, height] as explained in the documentation for "width" and "height". If <code>null</code> + * is returned nothing is done and this is the default. + * @see net.miginfocom.layout.BoundSize + * @see net.miginfocom.layout.ConstraintParser#parseBoundSize(String, boolean, boolean) + */ + public BoundSize[] getSize(ComponentWrapper comp) + { + return null; + } + + /** A last minute change of the bounds. The bound for the layout cycle has been set and you can correct there + * after any set of rules you like. + * @param comp The component wrapper that holds the actual component (JComponent is Swing and Control in SWT). + * <b>Should not be altered.</b> + */ + public void correctBounds(ComponentWrapper comp) + { + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/LayoutUtil.java b/prototypes/miglayout/net/miginfocom/layout/LayoutUtil.java index 05d0633a..badee305 100644 --- a/prototypes/miglayout/net/miginfocom/layout/LayoutUtil.java +++ b/prototypes/miglayout/net/miginfocom/layout/LayoutUtil.java @@ -1,532 +1,532 @@ -package net.miginfocom.layout;
-
-import java.beans.*;
-import java.io.*;
-import java.util.IdentityHashMap;
-import java.util.TreeSet;
-import java.util.WeakHashMap;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** A utility class that has only static helper methods.
- */
-public final class LayoutUtil
-{
- /** A substitute value for aa really large value. Integer.MAX_VALUE is not used since that means a lot of defensive code
- * for potential overflow must exist in many places. This value is large enough for being unresonable yet it is hard to
- * overflow.
- */
- static final int INF = (Integer.MAX_VALUE >> 10) - 100; // To reduce likelyhood of overflow errors when calculating.
-
- /** Tag int for a value that in considered "not set". Used as "null" element in int arays.
- */
- static final int NOT_SET = Integer.MIN_VALUE + 12346; // Magic value...
-
- // Index for the different sizes
- public static final int MIN = 0;
- public static final int PREF = 1;
- public static final int MAX = 2;
-
- private static WeakHashMap<Object, String> CR_MAP = null;
- private static WeakHashMap<Object, Boolean> DT_MAP = null; // The Containers that have design time. Value not used.
- private static int eSz = 15;
-
- private LayoutUtil()
- {
- }
-
- /** Returns the current version of MiG Layout.
- * @return The current version of MiG Layout.
- */
- public static String getVersion()
- {
- return "3.0.3";
- }
-
- /** Sets if design time is turned on for a Container in {@link ContainerWrapper}.
- * @param cw The container to set design time for. <code>null</code> is legal and can be used as
- * a key to turn on/off design time "in general". Note though that design time "in general" is
- * always on as long as there is at least one ContainerWrapper with design time.
- * <p>
- * <strong>If this method has not ever been called it will default to what
- * <code>Beans.isDesignTime()</code> returns.</strong> This means that if you call
- * this method you indicate that you will take responsibility for the design time value.
- * @param b <code>true</code> means design time on.
- */
- public static void setDesignTime(ContainerWrapper cw, boolean b)
- {
- if (DT_MAP == null)
- DT_MAP = new WeakHashMap<Object, Boolean>();
-
- DT_MAP.put((cw != null ? cw.getComponent() : null), new Boolean(b));
- }
-
- /** Returns if design time is turned on for a Container in {@link ContainerWrapper}.
- * @param cw The container to set design time for. <code>null</code> is legal will return <code>true</code>
- * if there is at least one <code>ContainerWrapper</code> (or <code>null</code>) that have design time
- * turned on.
- * @return If design time is set for <code>cw</code>.
- */
- public static boolean isDesignTime(ContainerWrapper cw)
- {
- if (DT_MAP == null)
- return Beans.isDesignTime();
-
- Boolean b = DT_MAP.get(cw != null ? cw.getComponent() : null);
- return b != null ? b.booleanValue() : false;
- }
-
- /** The size of an empty row or columns in a grid during design time.
- * @return The number of pixels. Default is 15.
- */
- public static int getDesignTimeEmptySize()
- {
- return eSz;
- }
-
- /** The size of an empty row or columns in a grid during design time.
- * @param pixels The number of pixels. Default is 15.
- */
- public static void setDesignTimeEmptySize(int pixels)
- {
- eSz = pixels;
- }
-
- /** Associates <code>con</code> with the creation string <code>s</code>. The <code>con</code> object should
- * probably have an equals method that compares identities or <code>con</code> objects that .equals() will only
- * be able to have <b>one</b> creation string.
- * <p>
- * If {@link LayoutUtil#isDesignTime(ContainerWrapper)} returns <code>false</code> the method does nothing.
- * @param con The object. if <code>null</code> the method does nothing.
- * @param s The creation string. if <code>null</code> the method does nothing.
- */
- static void putCCString(Object con, String s)
- {
- if (s != null && con != null && isDesignTime(null)) {
- if (CR_MAP == null)
- CR_MAP = new WeakHashMap<Object, String>(64);
-
- CR_MAP.put(con, s);
- }
- }
-
- /** Sets/add the persistence delagates to be used for a class.
- * @param c The class to set the registered deligate for.
- * @param del The new deligate or <code>null</code> to erase to old one.
- */
- static synchronized void setDelegate(Class c, PersistenceDelegate del)
- {
- try {
- Introspector.getBeanInfo(c).getBeanDescriptor().setValue("persistenceDelegate", del);
- } catch (Exception e1) {
- }
- }
-
- /** Returns strings set with {@link #putCCString(Object, String)} or <code>null</code> if nothing is associated or
- * {@link LayoutUtil#isDesignTime(ContainerWrapper)} returns <code>false</code>.
- * @param con The constraitn object.
- * @return The creation string or <code>null</code> if nothing is registered with the <code>con</code> object.
- */
- static String getCCString(Object con)
- {
- return CR_MAP != null ? CR_MAP.get(con) : null;
- }
-
- static void throwCC()
- {
- throw new IllegalStateException("setStoreConstraintData(true) must be set for strings to be saved.");
- }
-
- /** Takes a number on min/preferred/max sizes and resize constraints and returns the calculated sizes which sum should add up to <code>bounds</code>. Whether the sum
- * will actually equal <code>bounds</code> is dependent om the pref/max sizes and resise constraints.
- * @param sizes [ix],[MIN][PREF][MAX]. Grid.CompWrap.NOT_SET will be treated as N/A or 0. A "[MIN][PREF][MAX]" array with null elements will be interpreted as very flexible (no bounds)
- * but if the array itself is null it will not get any size.
- * @param resConstr Elements can be <code>null</code> and the whole array can be <code>null</code>. <code>null</code> means that the size will not be flexible at all.
- * Can have length less than <code>sizes</code> in which case the last element should be used for the elements missing.
- * @param defGrowWeights If there is no grow weight for a resConstr the correspinding value of this array is used.
- * These forced resConstr will be grown last though and only if needed to fill to the bounds.
- * @param startSizeType The initial size to use. E.g. {@link net.miginfocom.layout.LayoutUtil#MIN}.
- * @param bounds To use for relative sizes.
- * @return The sizes. Array length will match <code>sizes</code>.
- */
- static int[] calculateSerial(int[][] sizes, ResizeConstraint[] resConstr, Float[] defGrowWeights, int startSizeType, int bounds)
- {
- float[] lengths = new float[sizes.length]; // heights/widths that are set
- float usedLength = 0.0f;
-
- // Give all preferred size to start with
- for (int i = 0; i < sizes.length; i++) {
- if (sizes[i] != null) {
- float len = sizes[i][startSizeType] != NOT_SET ? sizes[i][startSizeType] : 0;
- int newSizeBounded = getBrokenBoundary(len, sizes[i][MIN], sizes[i][MAX]);
- if (newSizeBounded != NOT_SET)
- len = newSizeBounded;
-
- usedLength += len;
- lengths[i] = len;
- }
- }
-
- int useLengthI = Math.round(usedLength);
- if (useLengthI != bounds && resConstr != null) {
- boolean isGrow = useLengthI < bounds;
-
- // Create a Set with the available priorities
- TreeSet<Integer> prioList = new TreeSet<Integer>();
- for (int i = 0; i < sizes.length; i++) {
- ResizeConstraint resC = (ResizeConstraint) getIndexSafe(resConstr, i);
- if (resC != null)
- prioList.add(new Integer(isGrow ? resC.growPrio : resC.shrinkPrio));
- }
- Integer[] prioIntegers = prioList.toArray(new Integer[prioList.size()]);
-
- for (int force = 0; force <= ((isGrow && defGrowWeights != null) ? 1 : 0); force++) { // Run twice if defGrow and the need for growing.
- for (int pr = prioIntegers.length - 1; pr >= 0; pr--) {
- int curPrio = prioIntegers[pr].intValue();
-
- float totWeight = 0f;
- Float[] resizeWeight = new Float[sizes.length];
- for (int i = 0; i < sizes.length; i++) {
- if (sizes[i] == null) // if no min/pref/max size at all do not grow or shrink.
- continue;
-
- ResizeConstraint resC = (ResizeConstraint) getIndexSafe(resConstr, i);
- if (resC != null) {
- int prio = isGrow ? resC.growPrio : resC.shrinkPrio;
-
- if (curPrio == prio) {
- if (isGrow) {
- resizeWeight[i] = (force == 0 || resC.grow != null) ? resC.grow : (defGrowWeights[i < defGrowWeights.length ? i : defGrowWeights.length - 1]);
- } else {
- resizeWeight[i] = resC.shrink;
- }
- if (resizeWeight[i] != null)
- totWeight += resizeWeight[i].floatValue();
- }
- }
- }
-
- if (totWeight > 0f) {
- boolean hit;
- do {
- float toChange = bounds - usedLength;
- hit = false;
- float changedWeight = 0f;
- for (int i = 0; i < sizes.length && totWeight > 0.0001f; i++) {
-
- Float weight = resizeWeight[i];
- if (weight != null) {
- float sizeDelta = toChange * weight.floatValue() / totWeight;
- float newSize = lengths[i] + sizeDelta;
-
- if (sizes[i] != null) {
- int newSizeBounded = getBrokenBoundary(newSize, sizes[i][MIN], sizes[i][MAX]);
- if (newSizeBounded != NOT_SET) {
- resizeWeight[i] = null;
- hit = true;
- changedWeight += weight.floatValue();
- newSize = newSizeBounded;
- sizeDelta = newSize - lengths[i];
- }
- }
-
- lengths[i] = newSize;
- usedLength += sizeDelta;
- }
- }
- totWeight -= changedWeight;
- } while (hit);
- }
- }
- }
- }
- return roundSizes(lengths);
- }
-
- static Object getIndexSafe(Object[] arr, int ix)
- {
- return arr != null ? arr[ix < arr.length ? ix : arr.length - 1] : null;
- }
-
- /** Returns the broken boundary if <code>sz</code> is outside the boundaries <code>lower</code> or <code>upper</code>. If both boundaries
- * are broken, the lower one is returned. If <code>sz</code> is < 0 then <code>new Float(0f)</code> is returned so that no sizes can be
- * negative.
- * @param sz The size to check
- * @param lower The lower boundary (or <code>null</code> fo no boundary).
- * @param upper The upper boundary (or <code>null</code> fo no boundary).
- * @return The broken boundary or <code>null</code> if no boundary was broken.
- */
- private static int getBrokenBoundary(float sz, int lower, int upper)
- {
- if (lower != NOT_SET) {
- if (sz < lower)
- return new Integer(lower);
- } else if (sz < 0f) {
- return new Integer(0);
- }
-
- if (upper != NOT_SET && sz > upper)
- return new Integer(upper);
-
- return NOT_SET;
- }
-
-
- static int sum(int[] terms, int start, int len)
- {
- int s = 0;
- for (int i = start, iSz = start + len; i < iSz; i++)
- s += terms[i];
- return s;
- }
-
- static int sum(int[] terms)
- {
- return sum(terms, 0, terms.length);
- }
-
- public static int getSizeSafe(int[] sizes, int sizeType)
- {
- if (sizes == null || sizes[sizeType] == NOT_SET)
- return sizeType == MAX ? LayoutUtil.INF : 0;
- return sizes[sizeType];
- }
-
- static BoundSize derive(BoundSize bs, UnitValue min, UnitValue pref, UnitValue max)
- {
- if (bs == null)
- return new BoundSize(min, pref, max, null);
-
- return new BoundSize(
- min != null ? min : bs.getMin(),
- pref != null ? pref : bs.getPreferred(),
- max != null ? max : bs.getMax(), null);
- }
-
- /** Returns if left-to-right orientation is used. If not set explicitly in the layout constraints the Locale
- * of the <code>parent</code> is used.
- * @param lc The constraint if there is one. Can be <code>null</code>.
- * @param container The parent that may be used to get the left-to-right if ffc does not specify this.
- * @return If left-to-right orientation is currently used.
- */
- public final static boolean isLeftToRight(LC lc, ContainerWrapper container)
- {
- if (lc != null && lc.getLeftToRight() != null)
- return lc.getLeftToRight().booleanValue();
-
- return container == null || container.isLeftToRight();
- }
-
- /** Round a number of float sizes into int sizes so that the total length match up
- * @param sizes The sizes to round
- * @return An array of equal length as <code>sizes</code>.
- */
- static int[] roundSizes(float[] sizes)
- {
- int[] retInts = new int[sizes.length];
- float posD = 0;
-
- for (int i = 0; i < retInts.length; i++) {
- int posI = (int) (posD + 0.5f);
-
- posD += sizes[i];
-
- retInts[i] = (int) (posD + 0.5f) - posI;
- }
-
- return retInts;
- }
-
- /** Safe equals. null == null, but null never equals anything else.
- * @param o1 The first object. May be <code>null</code>.
- * @param o2 The second object. May be <code>null</code>.
- * @return Returns <code>true</code> if <code>o1</code> and <code>o2</code> are equal (using .equals()) or both are <code>null</code>.
- */
- static final boolean equals(Object o1, Object o2)
- {
- return o1 == o2 || (o1 != null && o2 != null && o1.equals(o2));
- }
-
-// static int getBaselineCorrect(Component comp)
-// {
-// Dimension pSize = comp.getPreferredSize();
-// int baseline = comp.getBaseline(pSize.width, pSize.height);
-// int nextBaseline = comp.getBaseline(pSize.width, pSize.height + 1);
-//
-// // Amount to add to height when calculating where baseline
-// // lands for a particular height:
-// int padding = 0;
-//
-// // Where the baseline is relative to the mid point
-// int baselineOffset = baseline - pSize.height / 2;
-// if (pSize.height % 2 == 0 && baseline != nextBaseline) {
-// padding = 1;
-// } else if (pSize.height % 2 == 1 && baseline == nextBaseline) {
-// baselineOffset--;
-// padding = 1;
-// }
-//
-// // The following calculates where the baseline lands for
-// // the height z:
-// return (pSize.height + padding) / 2 + baselineOffset;
-// }
-
- /** Converts a <code>float</code> to a string and is removing the ".0" if the float is an integer.
- * @param f the float.
- * @return <code>f</code> as a string. Never <code>null</code>.
- */
- static final String floatToString(float f)
- {
- String valS = String.valueOf(f);
- return valS.endsWith(".0") ? valS.substring(0, valS.length() - 2) : valS;
- }
-
- /** Returns the inset for the side.
- * @param side top == 0, left == 1, bottom = 2, right = 3.
- * @param getDefault If <code>true</code> the default insets will get retrieved if <code>lc</code> has none set.
- * @return The inset for the side. Never <code>null</code>.
- */
- static final UnitValue getInsets(LC lc, int side, boolean getDefault)
- {
- UnitValue[] i = lc.getInsets();
- return (i != null && i[side] != null) ? i[side] : (getDefault ? PlatformDefaults.getPanelInsets(side) : UnitValue.ZERO);
- }
-
- /** Writes the objet and CLOSES the stream. Uses the persistence delegate registered in this class.
- * @param os The stream to write to. Will be closed.
- * @param o The object to be serialized.
- * @param listener The listener to recieve the exeptions if there are any. If <code>null</code> not used.
- */
- static void writeXMLObject(OutputStream os, Object o, ExceptionListener listener)
- {
- ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(LayoutUtil.class.getClassLoader());
-
- XMLEncoder encoder = new XMLEncoder(os);
-
- if (listener != null)
- encoder.setExceptionListener(listener);
-
- encoder.writeObject(o);
- encoder.close(); // Must be closed to write.
-
- Thread.currentThread().setContextClassLoader(oldClassLoader);
- }
-
- private static ByteArrayOutputStream writeOutputStream = null;
- /** Writes an object to XML.
- * @param out The boject out to write to. Will not be closed.
- * @param o The object to write.
- */
- public static synchronized void writeAsXML(ObjectOutput out, Object o) throws IOException
- {
- if (writeOutputStream == null)
- writeOutputStream = new ByteArrayOutputStream(16384);
-
- writeOutputStream.reset();
-
- writeXMLObject(writeOutputStream, o, new ExceptionListener() {
- public void exceptionThrown(Exception e) {
- e.printStackTrace();
- }});
-
- byte[] buf = writeOutputStream.toByteArray();
-
- out.writeInt(buf.length);
- out.write(buf);
- }
-
- private static byte[] readBuf = null;
- /** Reads an object from <code>in</code> using the
- * @param in The object input to read from.
- * @return The object. Never <code>null</code>.
- * @throws IOException If there was a problem saving as XML
- */
- public static synchronized Object readAsXML(ObjectInput in) throws IOException
- {
- if (readBuf == null)
- readBuf = new byte[16384];
-
- Thread cThread = Thread.currentThread();
- ClassLoader oldCL = null;
-
- try {
- oldCL = cThread.getContextClassLoader();
- cThread.setContextClassLoader(LayoutUtil.class.getClassLoader());
- } catch(SecurityException e) {
- }
-
- Object o = null;
- try {
- int length = in.readInt();
- if (length > readBuf.length)
- readBuf = new byte[length];
-
- in.readFully(readBuf, 0, length);
-
- o = new XMLDecoder(new ByteArrayInputStream(readBuf, 0, length)).readObject();
-
- } catch(EOFException e) {
- }
-
- if (oldCL != null)
- cThread.setContextClassLoader(oldCL);
-
- return o;
- }
-
- private static final IdentityHashMap<Object, Object> SER_MAP = new IdentityHashMap<Object, Object>(2);
-
- /** Sets the serialized object and associates it with <code>caller</code>.
- * @param caller The objec created <code>o</code>
- * @param o The just serialized object.
- */
- public static void setSerializedObject(Object caller, Object o)
- {
- synchronized(SER_MAP) {
- SER_MAP.put(caller, o);
- }
- }
-
- /** Returns the serialized object that are associated with <code>caller</code>. It also removes it from the list.
- * @param caller The original creator of the object.
- * @return The object.
- */
- public static Object getSerializedObject(Object caller)
- {
- synchronized(SER_MAP) {
- return SER_MAP.remove(caller);
- }
- }
-}
+package net.miginfocom.layout; + +import java.beans.*; +import java.io.*; +import java.util.IdentityHashMap; +import java.util.TreeSet; +import java.util.WeakHashMap; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** A utility class that has only static helper methods. + */ +public final class LayoutUtil +{ + /** A substitute value for aa really large value. Integer.MAX_VALUE is not used since that means a lot of defensive code + * for potential overflow must exist in many places. This value is large enough for being unresonable yet it is hard to + * overflow. + */ + static final int INF = (Integer.MAX_VALUE >> 10) - 100; // To reduce likelyhood of overflow errors when calculating. + + /** Tag int for a value that in considered "not set". Used as "null" element in int arays. + */ + static final int NOT_SET = Integer.MIN_VALUE + 12346; // Magic value... + + // Index for the different sizes + public static final int MIN = 0; + public static final int PREF = 1; + public static final int MAX = 2; + + private static WeakHashMap<Object, String> CR_MAP = null; + private static WeakHashMap<Object, Boolean> DT_MAP = null; // The Containers that have design time. Value not used. + private static int eSz = 15; + + private LayoutUtil() + { + } + + /** Returns the current version of MiG Layout. + * @return The current version of MiG Layout. + */ + public static String getVersion() + { + return "3.0.3"; + } + + /** Sets if design time is turned on for a Container in {@link ContainerWrapper}. + * @param cw The container to set design time for. <code>null</code> is legal and can be used as + * a key to turn on/off design time "in general". Note though that design time "in general" is + * always on as long as there is at least one ContainerWrapper with design time. + * <p> + * <strong>If this method has not ever been called it will default to what + * <code>Beans.isDesignTime()</code> returns.</strong> This means that if you call + * this method you indicate that you will take responsibility for the design time value. + * @param b <code>true</code> means design time on. + */ + public static void setDesignTime(ContainerWrapper cw, boolean b) + { + if (DT_MAP == null) + DT_MAP = new WeakHashMap<Object, Boolean>(); + + DT_MAP.put((cw != null ? cw.getComponent() : null), new Boolean(b)); + } + + /** Returns if design time is turned on for a Container in {@link ContainerWrapper}. + * @param cw The container to set design time for. <code>null</code> is legal will return <code>true</code> + * if there is at least one <code>ContainerWrapper</code> (or <code>null</code>) that have design time + * turned on. + * @return If design time is set for <code>cw</code>. + */ + public static boolean isDesignTime(ContainerWrapper cw) + { + if (DT_MAP == null) + return Beans.isDesignTime(); + + Boolean b = DT_MAP.get(cw != null ? cw.getComponent() : null); + return b != null ? b.booleanValue() : false; + } + + /** The size of an empty row or columns in a grid during design time. + * @return The number of pixels. Default is 15. + */ + public static int getDesignTimeEmptySize() + { + return eSz; + } + + /** The size of an empty row or columns in a grid during design time. + * @param pixels The number of pixels. Default is 15. + */ + public static void setDesignTimeEmptySize(int pixels) + { + eSz = pixels; + } + + /** Associates <code>con</code> with the creation string <code>s</code>. The <code>con</code> object should + * probably have an equals method that compares identities or <code>con</code> objects that .equals() will only + * be able to have <b>one</b> creation string. + * <p> + * If {@link LayoutUtil#isDesignTime(ContainerWrapper)} returns <code>false</code> the method does nothing. + * @param con The object. if <code>null</code> the method does nothing. + * @param s The creation string. if <code>null</code> the method does nothing. + */ + static void putCCString(Object con, String s) + { + if (s != null && con != null && isDesignTime(null)) { + if (CR_MAP == null) + CR_MAP = new WeakHashMap<Object, String>(64); + + CR_MAP.put(con, s); + } + } + + /** Sets/add the persistence delagates to be used for a class. + * @param c The class to set the registered deligate for. + * @param del The new deligate or <code>null</code> to erase to old one. + */ + static synchronized void setDelegate(Class c, PersistenceDelegate del) + { + try { + Introspector.getBeanInfo(c).getBeanDescriptor().setValue("persistenceDelegate", del); + } catch (Exception e1) { + } + } + + /** Returns strings set with {@link #putCCString(Object, String)} or <code>null</code> if nothing is associated or + * {@link LayoutUtil#isDesignTime(ContainerWrapper)} returns <code>false</code>. + * @param con The constraitn object. + * @return The creation string or <code>null</code> if nothing is registered with the <code>con</code> object. + */ + static String getCCString(Object con) + { + return CR_MAP != null ? CR_MAP.get(con) : null; + } + + static void throwCC() + { + throw new IllegalStateException("setStoreConstraintData(true) must be set for strings to be saved."); + } + + /** Takes a number on min/preferred/max sizes and resize constraints and returns the calculated sizes which sum should add up to <code>bounds</code>. Whether the sum + * will actually equal <code>bounds</code> is dependent om the pref/max sizes and resise constraints. + * @param sizes [ix],[MIN][PREF][MAX]. Grid.CompWrap.NOT_SET will be treated as N/A or 0. A "[MIN][PREF][MAX]" array with null elements will be interpreted as very flexible (no bounds) + * but if the array itself is null it will not get any size. + * @param resConstr Elements can be <code>null</code> and the whole array can be <code>null</code>. <code>null</code> means that the size will not be flexible at all. + * Can have length less than <code>sizes</code> in which case the last element should be used for the elements missing. + * @param defGrowWeights If there is no grow weight for a resConstr the correspinding value of this array is used. + * These forced resConstr will be grown last though and only if needed to fill to the bounds. + * @param startSizeType The initial size to use. E.g. {@link net.miginfocom.layout.LayoutUtil#MIN}. + * @param bounds To use for relative sizes. + * @return The sizes. Array length will match <code>sizes</code>. + */ + static int[] calculateSerial(int[][] sizes, ResizeConstraint[] resConstr, Float[] defGrowWeights, int startSizeType, int bounds) + { + float[] lengths = new float[sizes.length]; // heights/widths that are set + float usedLength = 0.0f; + + // Give all preferred size to start with + for (int i = 0; i < sizes.length; i++) { + if (sizes[i] != null) { + float len = sizes[i][startSizeType] != NOT_SET ? sizes[i][startSizeType] : 0; + int newSizeBounded = getBrokenBoundary(len, sizes[i][MIN], sizes[i][MAX]); + if (newSizeBounded != NOT_SET) + len = newSizeBounded; + + usedLength += len; + lengths[i] = len; + } + } + + int useLengthI = Math.round(usedLength); + if (useLengthI != bounds && resConstr != null) { + boolean isGrow = useLengthI < bounds; + + // Create a Set with the available priorities + TreeSet<Integer> prioList = new TreeSet<Integer>(); + for (int i = 0; i < sizes.length; i++) { + ResizeConstraint resC = (ResizeConstraint) getIndexSafe(resConstr, i); + if (resC != null) + prioList.add(new Integer(isGrow ? resC.growPrio : resC.shrinkPrio)); + } + Integer[] prioIntegers = prioList.toArray(new Integer[prioList.size()]); + + for (int force = 0; force <= ((isGrow && defGrowWeights != null) ? 1 : 0); force++) { // Run twice if defGrow and the need for growing. + for (int pr = prioIntegers.length - 1; pr >= 0; pr--) { + int curPrio = prioIntegers[pr].intValue(); + + float totWeight = 0f; + Float[] resizeWeight = new Float[sizes.length]; + for (int i = 0; i < sizes.length; i++) { + if (sizes[i] == null) // if no min/pref/max size at all do not grow or shrink. + continue; + + ResizeConstraint resC = (ResizeConstraint) getIndexSafe(resConstr, i); + if (resC != null) { + int prio = isGrow ? resC.growPrio : resC.shrinkPrio; + + if (curPrio == prio) { + if (isGrow) { + resizeWeight[i] = (force == 0 || resC.grow != null) ? resC.grow : (defGrowWeights[i < defGrowWeights.length ? i : defGrowWeights.length - 1]); + } else { + resizeWeight[i] = resC.shrink; + } + if (resizeWeight[i] != null) + totWeight += resizeWeight[i].floatValue(); + } + } + } + + if (totWeight > 0f) { + boolean hit; + do { + float toChange = bounds - usedLength; + hit = false; + float changedWeight = 0f; + for (int i = 0; i < sizes.length && totWeight > 0.0001f; i++) { + + Float weight = resizeWeight[i]; + if (weight != null) { + float sizeDelta = toChange * weight.floatValue() / totWeight; + float newSize = lengths[i] + sizeDelta; + + if (sizes[i] != null) { + int newSizeBounded = getBrokenBoundary(newSize, sizes[i][MIN], sizes[i][MAX]); + if (newSizeBounded != NOT_SET) { + resizeWeight[i] = null; + hit = true; + changedWeight += weight.floatValue(); + newSize = newSizeBounded; + sizeDelta = newSize - lengths[i]; + } + } + + lengths[i] = newSize; + usedLength += sizeDelta; + } + } + totWeight -= changedWeight; + } while (hit); + } + } + } + } + return roundSizes(lengths); + } + + static Object getIndexSafe(Object[] arr, int ix) + { + return arr != null ? arr[ix < arr.length ? ix : arr.length - 1] : null; + } + + /** Returns the broken boundary if <code>sz</code> is outside the boundaries <code>lower</code> or <code>upper</code>. If both boundaries + * are broken, the lower one is returned. If <code>sz</code> is < 0 then <code>new Float(0f)</code> is returned so that no sizes can be + * negative. + * @param sz The size to check + * @param lower The lower boundary (or <code>null</code> fo no boundary). + * @param upper The upper boundary (or <code>null</code> fo no boundary). + * @return The broken boundary or <code>null</code> if no boundary was broken. + */ + private static int getBrokenBoundary(float sz, int lower, int upper) + { + if (lower != NOT_SET) { + if (sz < lower) + return new Integer(lower); + } else if (sz < 0f) { + return new Integer(0); + } + + if (upper != NOT_SET && sz > upper) + return new Integer(upper); + + return NOT_SET; + } + + + static int sum(int[] terms, int start, int len) + { + int s = 0; + for (int i = start, iSz = start + len; i < iSz; i++) + s += terms[i]; + return s; + } + + static int sum(int[] terms) + { + return sum(terms, 0, terms.length); + } + + public static int getSizeSafe(int[] sizes, int sizeType) + { + if (sizes == null || sizes[sizeType] == NOT_SET) + return sizeType == MAX ? LayoutUtil.INF : 0; + return sizes[sizeType]; + } + + static BoundSize derive(BoundSize bs, UnitValue min, UnitValue pref, UnitValue max) + { + if (bs == null) + return new BoundSize(min, pref, max, null); + + return new BoundSize( + min != null ? min : bs.getMin(), + pref != null ? pref : bs.getPreferred(), + max != null ? max : bs.getMax(), null); + } + + /** Returns if left-to-right orientation is used. If not set explicitly in the layout constraints the Locale + * of the <code>parent</code> is used. + * @param lc The constraint if there is one. Can be <code>null</code>. + * @param container The parent that may be used to get the left-to-right if ffc does not specify this. + * @return If left-to-right orientation is currently used. + */ + public final static boolean isLeftToRight(LC lc, ContainerWrapper container) + { + if (lc != null && lc.getLeftToRight() != null) + return lc.getLeftToRight().booleanValue(); + + return container == null || container.isLeftToRight(); + } + + /** Round a number of float sizes into int sizes so that the total length match up + * @param sizes The sizes to round + * @return An array of equal length as <code>sizes</code>. + */ + static int[] roundSizes(float[] sizes) + { + int[] retInts = new int[sizes.length]; + float posD = 0; + + for (int i = 0; i < retInts.length; i++) { + int posI = (int) (posD + 0.5f); + + posD += sizes[i]; + + retInts[i] = (int) (posD + 0.5f) - posI; + } + + return retInts; + } + + /** Safe equals. null == null, but null never equals anything else. + * @param o1 The first object. May be <code>null</code>. + * @param o2 The second object. May be <code>null</code>. + * @return Returns <code>true</code> if <code>o1</code> and <code>o2</code> are equal (using .equals()) or both are <code>null</code>. + */ + static final boolean equals(Object o1, Object o2) + { + return o1 == o2 || (o1 != null && o2 != null && o1.equals(o2)); + } + +// static int getBaselineCorrect(Component comp) +// { +// Dimension pSize = comp.getPreferredSize(); +// int baseline = comp.getBaseline(pSize.width, pSize.height); +// int nextBaseline = comp.getBaseline(pSize.width, pSize.height + 1); +// +// // Amount to add to height when calculating where baseline +// // lands for a particular height: +// int padding = 0; +// +// // Where the baseline is relative to the mid point +// int baselineOffset = baseline - pSize.height / 2; +// if (pSize.height % 2 == 0 && baseline != nextBaseline) { +// padding = 1; +// } else if (pSize.height % 2 == 1 && baseline == nextBaseline) { +// baselineOffset--; +// padding = 1; +// } +// +// // The following calculates where the baseline lands for +// // the height z: +// return (pSize.height + padding) / 2 + baselineOffset; +// } + + /** Converts a <code>float</code> to a string and is removing the ".0" if the float is an integer. + * @param f the float. + * @return <code>f</code> as a string. Never <code>null</code>. + */ + static final String floatToString(float f) + { + String valS = String.valueOf(f); + return valS.endsWith(".0") ? valS.substring(0, valS.length() - 2) : valS; + } + + /** Returns the inset for the side. + * @param side top == 0, left == 1, bottom = 2, right = 3. + * @param getDefault If <code>true</code> the default insets will get retrieved if <code>lc</code> has none set. + * @return The inset for the side. Never <code>null</code>. + */ + static final UnitValue getInsets(LC lc, int side, boolean getDefault) + { + UnitValue[] i = lc.getInsets(); + return (i != null && i[side] != null) ? i[side] : (getDefault ? PlatformDefaults.getPanelInsets(side) : UnitValue.ZERO); + } + + /** Writes the objet and CLOSES the stream. Uses the persistence delegate registered in this class. + * @param os The stream to write to. Will be closed. + * @param o The object to be serialized. + * @param listener The listener to recieve the exeptions if there are any. If <code>null</code> not used. + */ + static void writeXMLObject(OutputStream os, Object o, ExceptionListener listener) + { + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(LayoutUtil.class.getClassLoader()); + + XMLEncoder encoder = new XMLEncoder(os); + + if (listener != null) + encoder.setExceptionListener(listener); + + encoder.writeObject(o); + encoder.close(); // Must be closed to write. + + Thread.currentThread().setContextClassLoader(oldClassLoader); + } + + private static ByteArrayOutputStream writeOutputStream = null; + /** Writes an object to XML. + * @param out The boject out to write to. Will not be closed. + * @param o The object to write. + */ + public static synchronized void writeAsXML(ObjectOutput out, Object o) throws IOException + { + if (writeOutputStream == null) + writeOutputStream = new ByteArrayOutputStream(16384); + + writeOutputStream.reset(); + + writeXMLObject(writeOutputStream, o, new ExceptionListener() { + public void exceptionThrown(Exception e) { + e.printStackTrace(); + }}); + + byte[] buf = writeOutputStream.toByteArray(); + + out.writeInt(buf.length); + out.write(buf); + } + + private static byte[] readBuf = null; + /** Reads an object from <code>in</code> using the + * @param in The object input to read from. + * @return The object. Never <code>null</code>. + * @throws IOException If there was a problem saving as XML + */ + public static synchronized Object readAsXML(ObjectInput in) throws IOException + { + if (readBuf == null) + readBuf = new byte[16384]; + + Thread cThread = Thread.currentThread(); + ClassLoader oldCL = null; + + try { + oldCL = cThread.getContextClassLoader(); + cThread.setContextClassLoader(LayoutUtil.class.getClassLoader()); + } catch(SecurityException e) { + } + + Object o = null; + try { + int length = in.readInt(); + if (length > readBuf.length) + readBuf = new byte[length]; + + in.readFully(readBuf, 0, length); + + o = new XMLDecoder(new ByteArrayInputStream(readBuf, 0, length)).readObject(); + + } catch(EOFException e) { + } + + if (oldCL != null) + cThread.setContextClassLoader(oldCL); + + return o; + } + + private static final IdentityHashMap<Object, Object> SER_MAP = new IdentityHashMap<Object, Object>(2); + + /** Sets the serialized object and associates it with <code>caller</code>. + * @param caller The objec created <code>o</code> + * @param o The just serialized object. + */ + public static void setSerializedObject(Object caller, Object o) + { + synchronized(SER_MAP) { + SER_MAP.put(caller, o); + } + } + + /** Returns the serialized object that are associated with <code>caller</code>. It also removes it from the list. + * @param caller The original creator of the object. + * @return The object. + */ + public static Object getSerializedObject(Object caller) + { + synchronized(SER_MAP) { + return SER_MAP.remove(caller); + } + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/LinkHandler.java b/prototypes/miglayout/net/miginfocom/layout/LinkHandler.java index 8984bea1..96df386d 100644 --- a/prototypes/miglayout/net/miginfocom/layout/LinkHandler.java +++ b/prototypes/miglayout/net/miginfocom/layout/LinkHandler.java @@ -1,182 +1,182 @@ -package net.miginfocom.layout;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashMap;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/**
- */
-public final class LinkHandler
-{
- public static final int X = 0;
- public static final int Y = 1;
- public static final int WIDTH = 2;
- public static final int HEIGHT = 3;
- public static final int X2 = 4;
- public static final int Y2 = 5;
-
- private static final ArrayList<WeakReference<Object>> LAYOUTS = new ArrayList<WeakReference<Object>>(4);
- private static final ArrayList<HashMap<String, int[]>> VALUES = new ArrayList<HashMap<String, int[]>>(4);
- private static final ArrayList<HashMap<String, int[]>> VALUES_TEMP = new ArrayList<HashMap<String, int[]>>(4);
-
- private LinkHandler()
- {
- }
-
- public synchronized static Integer getValue(Object layout, String key, int type)
- {
- Integer ret = null;
- boolean cont = true;
-
- for (int i = LAYOUTS.size() - 1; i >= 0; i--) {
- Object l = LAYOUTS.get(i).get();
- if (ret == null && l == layout) {
- int[] rect = VALUES_TEMP.get(i).get(key);
- if (cont && rect != null && rect[type] != LayoutUtil.NOT_SET) {
- ret = new Integer(rect[type]);
- } else {
- rect = VALUES.get(i).get(key);
- ret = (rect != null && rect[type] != LayoutUtil.NOT_SET) ? new Integer(rect[type]) : null;
- }
- cont = false;
- }
-
- if (l == null) {
- LAYOUTS.remove(i);
- VALUES.remove(i);
- VALUES_TEMP.remove(i);
- }
- }
- return ret;
- }
-
- public synchronized static boolean setBounds(Object layout, String key, int x, int y, int width, int height)
- {
- return setBounds(layout, key, x, y, width, height, false, false);
- }
-
- synchronized static boolean setBounds(Object layout, String key, int x, int y, int width, int height, boolean temporary, boolean incCur)
- {
- for (int i = LAYOUTS.size() - 1; i >= 0; i--) {
- Object l = LAYOUTS.get(i).get();
- if (l == layout) {
- HashMap<String, int[]> map = (temporary ? VALUES_TEMP : VALUES).get(i);
- int[] old = map.get(key);
-
- if (old == null || old[X] != x || old[Y] != y || old[WIDTH] != width || old[HEIGHT] != height) {
- if (old == null || incCur == false) {
- map.put(key, new int[] {x, y, width, height, x + width, y + height});
- return true;
- } else {
- boolean changed = false;
-
- if (x != LayoutUtil.NOT_SET) {
- if (old[X] == LayoutUtil.NOT_SET || x < old[X]) {
- old[X] = x;
- old[WIDTH] = old[X2] - x;
- changed = true;
- }
-
- if (width != LayoutUtil.NOT_SET) {
- int x2 = x + width;
- if (old[X2] == LayoutUtil.NOT_SET || x2 > old[X2]) {
- old[X2] = x2;
- old[WIDTH] = x2 - old[X];
- changed = true;
- }
- }
- }
-
- if (y != LayoutUtil.NOT_SET) {
- if (old[Y] == LayoutUtil.NOT_SET || y < old[Y]) {
- old[Y] = y;
- old[HEIGHT] = old[Y2] - y;
- changed = true;
- }
-
- if (height != LayoutUtil.NOT_SET) {
- int y2 = y + height;
- if (old[Y2] == LayoutUtil.NOT_SET || y2 > old[Y2]) {
- old[Y2] = y2;
- old[HEIGHT] = y2 - old[Y];
- changed = true;
- }
- }
- }
- return changed;
- }
- }
- return false;
- }
- }
-
- LAYOUTS.add(new WeakReference<Object>(layout));
- int[] bounds = new int[] {x, y, width, height, x + width, y + height};
-
- HashMap<String, int[]> values = new HashMap<String, int[]>(4);
- if (temporary)
- values.put(key, bounds);
- VALUES_TEMP.add(values);
-
- values = new HashMap<String, int[]>(4);
- if (temporary == false)
- values.put(key, bounds);
- VALUES.add(values);
-
- return true;
- }
-
- public synchronized static boolean clearBounds(Object layout, String key)
- {
- for (int i = LAYOUTS.size() - 1; i >= 0; i--) {
- Object l = LAYOUTS.get(i).get();
- if (l == layout)
- return VALUES.get(i).remove(key) != null;
- }
- return false;
- }
-
- synchronized static void clearTemporaryBounds(Object layout)
- {
- for (int i = LAYOUTS.size() - 1; i >= 0; i--) {
- Object l = LAYOUTS.get(i).get();
- if (l == layout) {
- VALUES_TEMP.get(i).clear();
- return;
- }
- }
- }
-}
+package net.miginfocom.layout; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.HashMap; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** + */ +public final class LinkHandler +{ + public static final int X = 0; + public static final int Y = 1; + public static final int WIDTH = 2; + public static final int HEIGHT = 3; + public static final int X2 = 4; + public static final int Y2 = 5; + + private static final ArrayList<WeakReference<Object>> LAYOUTS = new ArrayList<WeakReference<Object>>(4); + private static final ArrayList<HashMap<String, int[]>> VALUES = new ArrayList<HashMap<String, int[]>>(4); + private static final ArrayList<HashMap<String, int[]>> VALUES_TEMP = new ArrayList<HashMap<String, int[]>>(4); + + private LinkHandler() + { + } + + public synchronized static Integer getValue(Object layout, String key, int type) + { + Integer ret = null; + boolean cont = true; + + for (int i = LAYOUTS.size() - 1; i >= 0; i--) { + Object l = LAYOUTS.get(i).get(); + if (ret == null && l == layout) { + int[] rect = VALUES_TEMP.get(i).get(key); + if (cont && rect != null && rect[type] != LayoutUtil.NOT_SET) { + ret = new Integer(rect[type]); + } else { + rect = VALUES.get(i).get(key); + ret = (rect != null && rect[type] != LayoutUtil.NOT_SET) ? new Integer(rect[type]) : null; + } + cont = false; + } + + if (l == null) { + LAYOUTS.remove(i); + VALUES.remove(i); + VALUES_TEMP.remove(i); + } + } + return ret; + } + + public synchronized static boolean setBounds(Object layout, String key, int x, int y, int width, int height) + { + return setBounds(layout, key, x, y, width, height, false, false); + } + + synchronized static boolean setBounds(Object layout, String key, int x, int y, int width, int height, boolean temporary, boolean incCur) + { + for (int i = LAYOUTS.size() - 1; i >= 0; i--) { + Object l = LAYOUTS.get(i).get(); + if (l == layout) { + HashMap<String, int[]> map = (temporary ? VALUES_TEMP : VALUES).get(i); + int[] old = map.get(key); + + if (old == null || old[X] != x || old[Y] != y || old[WIDTH] != width || old[HEIGHT] != height) { + if (old == null || incCur == false) { + map.put(key, new int[] {x, y, width, height, x + width, y + height}); + return true; + } else { + boolean changed = false; + + if (x != LayoutUtil.NOT_SET) { + if (old[X] == LayoutUtil.NOT_SET || x < old[X]) { + old[X] = x; + old[WIDTH] = old[X2] - x; + changed = true; + } + + if (width != LayoutUtil.NOT_SET) { + int x2 = x + width; + if (old[X2] == LayoutUtil.NOT_SET || x2 > old[X2]) { + old[X2] = x2; + old[WIDTH] = x2 - old[X]; + changed = true; + } + } + } + + if (y != LayoutUtil.NOT_SET) { + if (old[Y] == LayoutUtil.NOT_SET || y < old[Y]) { + old[Y] = y; + old[HEIGHT] = old[Y2] - y; + changed = true; + } + + if (height != LayoutUtil.NOT_SET) { + int y2 = y + height; + if (old[Y2] == LayoutUtil.NOT_SET || y2 > old[Y2]) { + old[Y2] = y2; + old[HEIGHT] = y2 - old[Y]; + changed = true; + } + } + } + return changed; + } + } + return false; + } + } + + LAYOUTS.add(new WeakReference<Object>(layout)); + int[] bounds = new int[] {x, y, width, height, x + width, y + height}; + + HashMap<String, int[]> values = new HashMap<String, int[]>(4); + if (temporary) + values.put(key, bounds); + VALUES_TEMP.add(values); + + values = new HashMap<String, int[]>(4); + if (temporary == false) + values.put(key, bounds); + VALUES.add(values); + + return true; + } + + public synchronized static boolean clearBounds(Object layout, String key) + { + for (int i = LAYOUTS.size() - 1; i >= 0; i--) { + Object l = LAYOUTS.get(i).get(); + if (l == layout) + return VALUES.get(i).remove(key) != null; + } + return false; + } + + synchronized static void clearTemporaryBounds(Object layout) + { + for (int i = LAYOUTS.size() - 1; i >= 0; i--) { + Object l = LAYOUTS.get(i).get(); + if (l == layout) { + VALUES_TEMP.get(i).clear(); + return; + } + } + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/PlatformDefaults.java b/prototypes/miglayout/net/miginfocom/layout/PlatformDefaults.java index d805812a..52a34f72 100644 --- a/prototypes/miglayout/net/miginfocom/layout/PlatformDefaults.java +++ b/prototypes/miglayout/net/miginfocom/layout/PlatformDefaults.java @@ -1,675 +1,675 @@ -package net.miginfocom.layout;
-
-import javax.swing.*;
-import java.util.HashMap;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** Currently handles Windows and Mac OS X spacing.
- */
-public final class PlatformDefaults
-{
- private static int DEF_H_UNIT = UnitValue.LPX;
- private static int DEF_V_UNIT = UnitValue.LPY;
-
- private static InCellGapProvider GAP_PROVIDER = null;
-
- private static volatile int MOD_COUNT = 0;
-
- private static final UnitValue LPX4 = new UnitValue(4, UnitValue.LPX, null);
- private static final UnitValue LPX7 = new UnitValue(7, UnitValue.LPX, null);
- private static final UnitValue LPX8 = new UnitValue(8, UnitValue.LPX, null);
- private static final UnitValue LPX9 = new UnitValue(9, UnitValue.LPX, null);
- private static final UnitValue LPX10 = new UnitValue(10, UnitValue.LPX, null);
- private static final UnitValue LPX11 = new UnitValue(11, UnitValue.LPX, null);
- private static final UnitValue LPX12 = new UnitValue(12, UnitValue.LPX, null);
- private static final UnitValue LPX14 = new UnitValue(14, UnitValue.LPX, null);
- private static final UnitValue LPX16 = new UnitValue(16, UnitValue.LPX, null);
- private static final UnitValue LPX20 = new UnitValue(20, UnitValue.LPX, null);
-
- private static final UnitValue LPY4 = new UnitValue(4, UnitValue.LPY, null);
- private static final UnitValue LPY7 = new UnitValue(7, UnitValue.LPY, null);
- private static final UnitValue LPY8 = new UnitValue(8, UnitValue.LPY, null);
- private static final UnitValue LPY9 = new UnitValue(9, UnitValue.LPY, null);
- private static final UnitValue LPY10 = new UnitValue(10, UnitValue.LPY, null);
- private static final UnitValue LPY11 = new UnitValue(11, UnitValue.LPY, null);
- private static final UnitValue LPY12 = new UnitValue(12, UnitValue.LPY, null);
- private static final UnitValue LPY14 = new UnitValue(14, UnitValue.LPY, null);
- private static final UnitValue LPY16 = new UnitValue(16, UnitValue.LPY, null);
- private static final UnitValue LPY20 = new UnitValue(20, UnitValue.LPY, null);
-
- public static final int WINDOWS_XP = 0;
- public static final int MAC_OSX = 1;
-// private static final int GNOME = 2;
-// private static final int KDE = 3;
-
- private static int CUR_PLAF = WINDOWS_XP;
-
- // Used for holding values.
- private final static UnitValue[] PANEL_INS = new UnitValue[4];
- private final static UnitValue[] DIALOG_INS = new UnitValue[4];
-
- private static String BUTTON_FORMAT = null;
-
- private static final HashMap<String, UnitValue> HOR_DEFS = new HashMap<String, UnitValue>(32);
- private static final HashMap<String, UnitValue> VER_DEFS = new HashMap<String, UnitValue>(32);
- private static BoundSize DEF_VGAP = null, DEF_HGAP = null;
- static BoundSize RELATED_X = null, RELATED_Y = null, UNRELATED_X = null, UNRELATED_Y = null;
- private static UnitValue BUTT_WIDTH = null;
-
- private static Float horScale = null, verScale = null;
-
- /** I value indicating that the size of the font for the container of the component
- * will be used as a base for calculating the logical pixel size. This is much as how
- * Windows calculated DLU (dialog units).
- * @see net.miginfocom.layout.UnitValue#LPX
- * @see net.miginfocom.layout.UnitValue#LPY
- * @see #setLogicalPixelBase(int)
- */
- public static final int BASE_FONT_SIZE = 100;
-
- /** I value indicating that the screen DPI will be used as a base for calculating the
- * logical pixel size.
- * <p>
- * This is the default value.
- * @see net.miginfocom.layout.UnitValue#LPX
- * @see net.miginfocom.layout.UnitValue#LPY
- * @see #setLogicalPixelBase(int)
- * @see #setVerticalScaleFactor(Float)
- * @see #setHorizontalScaleFactor(Float)
- */
- public static final int BASE_SCALE_FACTOR = 101;
-
- /** I value indicating that the size of a logica pixel should always be a real pixel
- * and thus no compensation will be made.
- * @see net.miginfocom.layout.UnitValue#LPX
- * @see net.miginfocom.layout.UnitValue#LPY
- * @see #setLogicalPixelBase(int)
- */
- public static final int BASE_REAL_PIXEL = 102;
-
- private static int LP_BASE = BASE_SCALE_FACTOR;
-
- private static int BASE_DPI = 96;
-
- static {
- setPlatform(getCurrentPlatform());
- MOD_COUNT = 0;
- }
-
- /** Returns the platform that the JRE is running on currently.
- * @return The platform that the JRE is running on currently. E.g. {@link #MAC_OSX} or {@link #WINDOWS_XP}.
- */
- public static int getCurrentPlatform()
- {
- return System.getProperty("os.name").startsWith("Mac OS") ? MAC_OSX : WINDOWS_XP;
- }
-
- private PlatformDefaults()
- {
- }
-
- /** Set the defaults to the default for the platform
- * @param plaf The platform. <code>PlatformDefaults.WINDOWS</code> or <code>PlatformDefaults.MAC_OSX</code>
- */
- public static void setPlatform(int plaf)
- {
- if (plaf < WINDOWS_XP || plaf > MAC_OSX)
- throw new IllegalArgumentException("Unknown platform: " + plaf);
-
- CUR_PLAF = plaf;
- if (plaf == WINDOWS_XP) {
- setRelatedGap(LPX4, LPY4);
- setUnrelatedGap(LPX7, LPY9);
- setParagraphGap(LPX14, LPY14);
- setIndentGap(LPX9, LPY9);
- setGridCellGap(LPX4, LPY4);
-
- setMinimumButtonWidth(new UnitValue(75, UnitValue.LPX, null));
- setButtonOrder("L_E+U+YNBXOCAH_R");
- setDialogInsets(LPY11, LPX11, LPY11, LPX11);
- setPanelInsets(LPY7, LPX7, LPY7, LPX7);
- BASE_DPI = 96;
- } else {
- setRelatedGap(LPX8, LPY8);
- setUnrelatedGap(LPX12, LPY12);
- setParagraphGap(LPX16, LPY16);
- setIndentGap(LPX10, LPY10);
- setGridCellGap(LPX8, LPY8);
-
- setMinimumButtonWidth(new UnitValue(68, UnitValue.LPX, null));
- setButtonOrder("L_HE+U+NYBXCOA_R");
- setDialogInsets(LPY14, LPX20, LPY20, LPX20);
- setPanelInsets(LPY16, LPX16, LPY16, LPX16);
- BASE_DPI = 72;
- }
- }
-
- /** Returns the current platform
- * @return <code>PlatformDefaults.WINDOWS</code> or <code>PlatformDefaults.MAC_OSX</code>
- */
- public static int getPlatform()
- {
- return CUR_PLAF;
- }
-
- public static int getDefaultDPI()
- {
- return BASE_DPI;
- }
-
- /** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied
- * with. If <code>null</code> this will default to a scale that will scale the current screen to the default screen resolution
- * (72 DPI for Mac and 92 DPI for Windows).
- * @return The forced scale or <code>null</code> for default scaling.
- * @see #getHorizontalScaleFactor()
- * @see ComponentWrapper#getHorizontalScreenDPI()
- */
- public static Float
- getHorizontalScaleFactor()
- {
- return horScale;
- }
-
- /** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied
- * with. If <code>null</code> this will default to a scale that will scale the current screen to the default screen resolution
- * (72 DPI for Mac and 92 DPI for Windows).
- * @param f The forced scale or <code>null</code> for default scaling.
- * @see #getHorizontalScaleFactor()
- * @see ComponentWrapper#getHorizontalScreenDPI()
- */
- public static void setHorizontalScaleFactor(Float f)
- {
- if (horScale != f) {
- horScale = f;
- MOD_COUNT++;
- }
- }
-
- /** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied
- * with. If <code>null</code> this will default to a scale that will scale the current screen to the default screen resolution
- * (72 DPI for Mac and 92 DPI for Windows).
- * @return The forced scale or <code>null</code> for default scaling.
- * @see #getHorizontalScaleFactor()
- * @see ComponentWrapper#getVerticalScreenDPI()
- */
- public static Float getVerticalScaleFactor()
- {
- return verScale;
- }
-
- /** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied
- * with. If <code>null</code> this will default to a scale that will scale the current screen to the default screen resolution
- * (72 DPI for Mac and 92 DPI for Windows).
- * @param f The forced scale or <code>null</code> for default scaling.
- * @see #getHorizontalScaleFactor()
- * @see ComponentWrapper#getVerticalScreenDPI()
- */
- public static void setVerticalScaleFactor(Float f)
- {
- if (verScale != f) {
- verScale = f;
- MOD_COUNT++;
- }
- }
-
- /** What base value should be used to calculate logical pixel sizes.
- * @return The current base. Default is {@link #BASE_SCALE_FACTOR}
- * @see #BASE_FONT_SIZE
- * @see # BASE_SCREEN_DPI_FACTOR
- * @see #BASE_REAL_PIXEL
- */
- public static int getLogicalPixelBase()
- {
- return LP_BASE;
- }
-
- /** What base value should be used to calculate logical pixel sizes.
- * @param base The new base. Default is {@link #BASE_SCALE_FACTOR}
- * @see #BASE_FONT_SIZE
- * @see # BASE_SCREEN_DPI_FACTOR
- * @see #BASE_REAL_PIXEL
- */
- public static void setLogicalPixelBase(int base)
- {
- if (LP_BASE != base) {
- if (base < BASE_FONT_SIZE || base > BASE_SCALE_FACTOR)
- throw new IllegalArgumentException("Unrecognized base: " + base);
-
- LP_BASE = base;
- MOD_COUNT++;
- }
- }
-
- /** Sets gap value for components that are "related".
- * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- */
- public static void setRelatedGap(UnitValue x, UnitValue y)
- {
- setUnitValue(new String[] {"r", "rel", "related"}, x, y);
-
- RELATED_X = new BoundSize(x, x, null, "rel:rel");
- RELATED_Y = new BoundSize(y, y, null, "rel:rel");
- }
-
- /** Sets gap value for components that are "unrelated".
- * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- */
- public static void setUnrelatedGap(UnitValue x, UnitValue y)
- {
- setUnitValue(new String[] {"u", "unrel", "unrelated"}, x, y);
-
- UNRELATED_X = new BoundSize(x, x, null, "unrel:unrel");
- UNRELATED_Y = new BoundSize(y, y, null, "unrel:unrel");
- }
-
- /** Sets paragraph gap value for components.
- * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- */
- public static void setParagraphGap(UnitValue x, UnitValue y)
- {
- setUnitValue(new String[] {"p", "para", "paragraph"}, x, y);
- }
-
- /** Sets gap value for components that are "intended".
- * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- */
- public static void setIndentGap(UnitValue x, UnitValue y)
- {
- setUnitValue(new String[] {"i", "ind", "indent"}, x, y);
- }
-
- /** Sets gap between two cells in the grid. Note that this is not a gap between component IN a cell, that has to be set
- * on the component constraints. The value will be the min and preferred size of the gap.
- * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change.
- */
- public static void setGridCellGap(UnitValue x, UnitValue y)
- {
- if (x != null)
- DEF_HGAP = new BoundSize(x, x, null, null);
-
- if (y != null)
- DEF_VGAP = new BoundSize(y, y, null, null);
-
- MOD_COUNT++;
- }
-
- /** Sets the recommended minimum button width.
- * @param width The recommended minimum button width.
- */
- public static void setMinimumButtonWidth(UnitValue width)
- {
- BUTT_WIDTH = width;
- MOD_COUNT++;
- }
-
- /** Returns the recommended minimum button width depending on the current set platform.
- * @return The recommended minimum button width depending on the current set platform.
- */
- public static UnitValue getMinimumButtonWidth()
- {
- return BUTT_WIDTH;
- }
-
- /** Returns the unit value associated with the unit. (E.i. "related" or "indent"). Must be lower case.
- * @param unit The unit string.
- * @return Tthe unit value associated with the unit. <code>null</code> for unrecognized units.
- */
- public static UnitValue getUnitValueX(String unit)
- {
- return HOR_DEFS.get(unit);
- }
-
- /** Returns the unit value associated with the unit. (E.i. "related" or "indent"). Must be lower case.
- * @param unit The unit string.
- * @return Tthe unit value associated with the unit. <code>null</code> for unrecognized units.
- */
- public static UnitValue getUnitValueY(String unit)
- {
- return VER_DEFS.get(unit);
- }
-
- /** Sets the unit value assiciated with a unit string. This may be used to store values for new unit strings
- * or modify old. Note that if a built in unit (such as "related") is modified all versions of it must be
- * set (I.e. "r", "rel" and "related"). The build in values will be reset to the default ones if the platform
- * is re-set.
- * @param unitStrings The unit strings. E.g. "mu", "myunit". Will be converted to lower case and trimmed. Not <code>null</code>.
- * @param x The value for the horizontal dimension. If <code>null</code> the value is not changed.
- * @param y The value for the vertical dimension. Might be same object as for <code>x</code>. If <code>null</code> the value is not changed.
- */
- public static final void setUnitValue(String[] unitStrings, UnitValue x, UnitValue y)
- {
- for (int i = 0; i < unitStrings.length; i++) {
- String s = unitStrings[i].toLowerCase().trim();
- if (x != null)
- HOR_DEFS.put(s, x);
- if (y != null)
- VER_DEFS.put(s, y);
- }
- MOD_COUNT++;
- }
-
- /** Understands ("r", "rel", "related") OR ("u", "unrel", "unrelated") OR ("i", "ind", "indent") OR ("p", "para", "paragraph").
- */
- static final int convertToPixels(float value, String unit, boolean isHor, float ref, ContainerWrapper parent, ComponentWrapper comp)
- {
- UnitValue uv = (isHor ? HOR_DEFS : VER_DEFS).get(unit);
- return uv != null ? Math.round(value * uv.getPixels(ref, parent, comp)) : UnitConverter.UNABLE;
- }
-
- /** Returns the order for the typical buttons in a standard button bar. It is one letter per button type.
- * @return The button order.
- * @see #setButtonOrder(String)
- */
- public static final String getButtonOrder()
- {
- return BUTTON_FORMAT;
- }
-
- /** Sets the order for the typical buttons in a standard button bar. It is one letter per button type.
- * <p>
- * Letter in upper case will get the minimum button width that the {@link #getMinimumButtonWidth()} specifies
- * and letters in lower case will get the width the corrent look&feel specifies.
- * <p>
- * Gaps will never be added to before the first component or after the last component. However, '+' (push) will be
- * applied before and after as well, but with a minimum size of 0 if first/last so there will not be a gap
- * before or after.
- * <p>
- * If gaps are explicitly set on buttons they will never be reduced, but they may be increased.
- * <p>
- * These are the characters that can be used:
- * <ul>
- * <li><code>'L'</code> - Buttons with this style tag will staticall end up on the left end of the bar.
- * <li><code>'R'</code> - Buttons with this style tag will staticall end up on the right end of the bar.
- * <li><code>'H'</code> - A tag for the "help" button that normally is supposed to be on the right.
- * <li><code>'E'</code> - A tag for the "help2" button that normally is supposed to be on the left.
- * <li><code>'Y'</code> - A tag for the "yes" button.
- * <li><code>'N'</code> - A tag for the "no" button.
- * <li><code>'X'</code> - A tag for the "next >" or "forward >" button.
- * <li><code>'B'</code> - A tag for the "< back>" or "< previous" button.
- * <li><code>'I'</code> - A tag for the "finish".
- * <li><code>'A'</code> - A tag for the "apply" button.
- * <li><code>'C'</code> - A tag for the "cancel" or "close" button.
- * <li><code>'O'</code> - A tag for the "ok" or "done" button.
- * <li><code>'U'</code> - All Uncategorized, Other, or "Unknown" buttons. Tag will be "other".
- * <li><code>'+'</code> - A glue push gap that will take as much space as it can and at least an "unrelated" gap. (Platform dependant)
- * <li><code>'_'</code> - (underscore) An "unrelated" gap. (Platform dependant)
- * </ul>
- * <p>
- * Even though the style tags are normally applied to buttons this works with all components.
- * <p>
- * The normal style for MAC OS X is <code>"L_HE+U+FBI_NYCOA_R"</code> and for Windows is <code>"L_E+U+FBI_YNOCAH_R"</code>
- * @param order The new button order for the current platform.
- */
- public static final void setButtonOrder(String order)
- {
- BUTTON_FORMAT = order;
- MOD_COUNT++;
- }
-
- /** Returns the tag (used in the {@link CC}) for a char. The char is same as used in {@link #getButtonOrder()}.
- * @param c The char. Must be lower case!
- * @return The tag that corresponds to the char or <code>null</code> if the char is unrecognized.
- */
- static final String getTagForChar(char c)
- {
- switch (c) {
- case 'o':
- return "ok";
- case 'c':
- return "cancel";
- case 'h':
- return "help";
- case 'e':
- return "help2";
- case 'y':
- return "yes";
- case 'n':
- return "no";
- case 'a':
- return "apply";
- case 'x':
- return "next"; // a.k.a forward
- case 'b':
- return "back"; // a.k.a. previous
- case 'i':
- return "finish";
- case 'l':
- return "left";
- case 'r':
- return "right";
- case 'u':
- return "other";
- default:
- return null;
- }
- }
-
- /** Returns the platform recommended inter-cell gap in the horizontal (x) dimension..
- * @return The platform recommended inter-cell gap in the horizontal (x) dimension..
- */
- public static BoundSize getGridGapX()
- {
- return DEF_HGAP;
- }
-
- /** Returns the platform recommended inter-cell gap in the vertical (x) dimension..
- * @return The platform recommended inter-cell gap in the vertical (x) dimension..
- */
- public static BoundSize getGridGapY()
- {
- return DEF_VGAP;
- }
-
- /** Returns the default dialog inset depending of the current platform.
- * @param side top == 0, left == 1, bottom = 2, right = 3.
- * @return The inset. Never <code>null</code>.
- */
- public static UnitValue getDialogInsets(int side)
- {
- return DIALOG_INS[side];
- }
-
- /** Sets the default insets for a dialog. Values that are null will not be changed.
- * @param top The top inset. May be <code>null</code>.
- * @param left The left inset. May be <code>null</code>.
- * @param bottom The bottom inset. May be <code>null</code>.
- * @param right The right inset. May be <code>null</code>.
- */
- public static void setDialogInsets(UnitValue top, UnitValue left, UnitValue bottom, UnitValue right)
- {
- if (top != null)
- DIALOG_INS[0] = top;
- if (left != null)
- DIALOG_INS[1] = left;
- if (bottom != null)
- DIALOG_INS[2] = bottom;
- if (right != null)
- DIALOG_INS[3] = right;
-
- MOD_COUNT++;
- }
-
- /** Returns the default panel inset depending of the current platform.
- * @param side top == 0, left == 1, bottom = 2, right = 3.
- * @return The inset. Never <code>null</code>.
- */
- public static UnitValue getPanelInsets(int side)
- {
- return PANEL_INS[side];
- }
-
- /** Sets the default insets for a dialog. Values that are null will not be changed.
- * @param top The top inset. May be <code>null</code>.
- * @param left The left inset. May be <code>null</code>.
- * @param bottom The bottom inset. May be <code>null</code>.
- * @param right The right inset. May be <code>null</code>.
- */
- public static void setPanelInsets(UnitValue top, UnitValue left, UnitValue bottom, UnitValue right)
- {
- if (top != null)
- PANEL_INS[0] = top;
-
- if (left != null)
- PANEL_INS[1] = left;
-
- if (bottom != null)
- PANEL_INS[2] = bottom;
-
- if (right != null)
- PANEL_INS[3] = right;
-
- MOD_COUNT++;
- }
-
- /** Returns the percentage used for alignment for labels (0 is left, 50 is center and 100 is right).
- * @return The percentage used for alignment for labels
- */
- public static float getLabelAlignPercentage()
- {
- return CUR_PLAF == MAC_OSX ? 1f : 0f;
- }
-
- /** Returns the default gap between two components that <b>are in the same cell</b>.
- * @param comp The component that the gap is for. Never <code>null</code>.
- * @param adjacentComp The adjacent component if any. May be <code>null</code>.
- * @param adjacentSide What side the <code>adjacentComp</code> is on. {@link javax.swing.SwingUtilities#TOP} or
- * {@link javax.swing.SwingUtilities#LEFT} or {@link javax.swing.SwingUtilities#BOTTOM} or {@link javax.swing.SwingUtilities#RIGHT}.
- * @param tag The tag string that the component might be tagged with in the component constraints. May be <code>null</code>.
- * @param isLTR If it is left-to-right.
- * @return The default gap between two components or <code>null</code> if there should be no gap.
- */
- static BoundSize getDefaultComponentGap(ComponentWrapper comp, ComponentWrapper adjacentComp, int adjacentSide, String tag, boolean isLTR)
- {
- if (GAP_PROVIDER != null)
- return GAP_PROVIDER.getDefaultGap(comp, adjacentComp, adjacentSide, tag, isLTR);
-
- if (adjacentComp == null)
- return null;
-
-// if (adjacentComp == null || adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.TOP)
-// return null;
-
- return (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT) ? RELATED_X : RELATED_Y;
- }
-
- /** Returns the current gap privider or <code>null</code> if none is set and "related" should always be used.
- * @return The current gap privider or <code>null</code> if none is set and "related" should always be used.
- */
- public static InCellGapProvider getGapProvider()
- {
- return GAP_PROVIDER;
- }
-
- /** Sets the current gap privider or <code>null</code> if none is set and "related" should always be used.
- * @param provider The current gap privider or <code>null</code> if none is set and "related" should always be used.
- */
- public static void setGapProvider(InCellGapProvider provider)
- {
- GAP_PROVIDER = provider;
- }
-
- /** Returns how many times the defaults has been changed. This can be used as a light weight check to
- * see if layout caches needs to be refreshed.
- * @return How many times the defaults has been changed.
- */
- public static int getModCount()
- {
- return MOD_COUNT;
- }
-
- /** Tells all layout manager instances to revalidate and recalculated everything.
- */
- public void invalidate()
- {
- MOD_COUNT++;
- }
-
- /** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
- * @return The current default unit.
- * @see UnitValue#PIXEL
- * @see UnitValue#LPX
- */
- public final static int getDefaultHorizontalUnit()
- {
- return DEF_H_UNIT;
- }
-
- /** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
- * @param unit The new default unit.
- * @see UnitValue#PIXEL
- * @see UnitValue#LPX
- */
- public final static void setDefaultHorizontalUnit(int unit)
- {
- if (unit < UnitValue.PIXEL || unit > UnitValue.LABEL_ALIGN)
- throw new IllegalArgumentException("Illegal Unit: " + unit);
-
- if (DEF_H_UNIT != unit) {
- DEF_H_UNIT = unit;
- MOD_COUNT++;
- }
- }
-
- /** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
- * @return The current default unit.
- * @see UnitValue#PIXEL
- * @see UnitValue#LPY
- */
- public final static int getDefaultVerticalUnit()
- {
- return DEF_V_UNIT;
- }
-
- /** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
- * @param unit The new default unit.
- * @see UnitValue#PIXEL
- * @see UnitValue#LPY
- */
- public final static void setDefaultVerticalUnit(int unit)
- {
- if (unit < UnitValue.PIXEL || unit > UnitValue.LABEL_ALIGN)
- throw new IllegalArgumentException("Illegal Unit: " + unit);
-
- if (DEF_V_UNIT != unit) {
- DEF_V_UNIT = unit;
- MOD_COUNT++;
- }
- }
+package net.miginfocom.layout; + +import javax.swing.*; +import java.util.HashMap; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** Currently handles Windows and Mac OS X spacing. + */ +public final class PlatformDefaults +{ + private static int DEF_H_UNIT = UnitValue.LPX; + private static int DEF_V_UNIT = UnitValue.LPY; + + private static InCellGapProvider GAP_PROVIDER = null; + + private static volatile int MOD_COUNT = 0; + + private static final UnitValue LPX4 = new UnitValue(4, UnitValue.LPX, null); + private static final UnitValue LPX7 = new UnitValue(7, UnitValue.LPX, null); + private static final UnitValue LPX8 = new UnitValue(8, UnitValue.LPX, null); + private static final UnitValue LPX9 = new UnitValue(9, UnitValue.LPX, null); + private static final UnitValue LPX10 = new UnitValue(10, UnitValue.LPX, null); + private static final UnitValue LPX11 = new UnitValue(11, UnitValue.LPX, null); + private static final UnitValue LPX12 = new UnitValue(12, UnitValue.LPX, null); + private static final UnitValue LPX14 = new UnitValue(14, UnitValue.LPX, null); + private static final UnitValue LPX16 = new UnitValue(16, UnitValue.LPX, null); + private static final UnitValue LPX20 = new UnitValue(20, UnitValue.LPX, null); + + private static final UnitValue LPY4 = new UnitValue(4, UnitValue.LPY, null); + private static final UnitValue LPY7 = new UnitValue(7, UnitValue.LPY, null); + private static final UnitValue LPY8 = new UnitValue(8, UnitValue.LPY, null); + private static final UnitValue LPY9 = new UnitValue(9, UnitValue.LPY, null); + private static final UnitValue LPY10 = new UnitValue(10, UnitValue.LPY, null); + private static final UnitValue LPY11 = new UnitValue(11, UnitValue.LPY, null); + private static final UnitValue LPY12 = new UnitValue(12, UnitValue.LPY, null); + private static final UnitValue LPY14 = new UnitValue(14, UnitValue.LPY, null); + private static final UnitValue LPY16 = new UnitValue(16, UnitValue.LPY, null); + private static final UnitValue LPY20 = new UnitValue(20, UnitValue.LPY, null); + + public static final int WINDOWS_XP = 0; + public static final int MAC_OSX = 1; +// private static final int GNOME = 2; +// private static final int KDE = 3; + + private static int CUR_PLAF = WINDOWS_XP; + + // Used for holding values. + private final static UnitValue[] PANEL_INS = new UnitValue[4]; + private final static UnitValue[] DIALOG_INS = new UnitValue[4]; + + private static String BUTTON_FORMAT = null; + + private static final HashMap<String, UnitValue> HOR_DEFS = new HashMap<String, UnitValue>(32); + private static final HashMap<String, UnitValue> VER_DEFS = new HashMap<String, UnitValue>(32); + private static BoundSize DEF_VGAP = null, DEF_HGAP = null; + static BoundSize RELATED_X = null, RELATED_Y = null, UNRELATED_X = null, UNRELATED_Y = null; + private static UnitValue BUTT_WIDTH = null; + + private static Float horScale = null, verScale = null; + + /** I value indicating that the size of the font for the container of the component + * will be used as a base for calculating the logical pixel size. This is much as how + * Windows calculated DLU (dialog units). + * @see net.miginfocom.layout.UnitValue#LPX + * @see net.miginfocom.layout.UnitValue#LPY + * @see #setLogicalPixelBase(int) + */ + public static final int BASE_FONT_SIZE = 100; + + /** I value indicating that the screen DPI will be used as a base for calculating the + * logical pixel size. + * <p> + * This is the default value. + * @see net.miginfocom.layout.UnitValue#LPX + * @see net.miginfocom.layout.UnitValue#LPY + * @see #setLogicalPixelBase(int) + * @see #setVerticalScaleFactor(Float) + * @see #setHorizontalScaleFactor(Float) + */ + public static final int BASE_SCALE_FACTOR = 101; + + /** I value indicating that the size of a logica pixel should always be a real pixel + * and thus no compensation will be made. + * @see net.miginfocom.layout.UnitValue#LPX + * @see net.miginfocom.layout.UnitValue#LPY + * @see #setLogicalPixelBase(int) + */ + public static final int BASE_REAL_PIXEL = 102; + + private static int LP_BASE = BASE_SCALE_FACTOR; + + private static int BASE_DPI = 96; + + static { + setPlatform(getCurrentPlatform()); + MOD_COUNT = 0; + } + + /** Returns the platform that the JRE is running on currently. + * @return The platform that the JRE is running on currently. E.g. {@link #MAC_OSX} or {@link #WINDOWS_XP}. + */ + public static int getCurrentPlatform() + { + return System.getProperty("os.name").startsWith("Mac OS") ? MAC_OSX : WINDOWS_XP; + } + + private PlatformDefaults() + { + } + + /** Set the defaults to the default for the platform + * @param plaf The platform. <code>PlatformDefaults.WINDOWS</code> or <code>PlatformDefaults.MAC_OSX</code> + */ + public static void setPlatform(int plaf) + { + if (plaf < WINDOWS_XP || plaf > MAC_OSX) + throw new IllegalArgumentException("Unknown platform: " + plaf); + + CUR_PLAF = plaf; + if (plaf == WINDOWS_XP) { + setRelatedGap(LPX4, LPY4); + setUnrelatedGap(LPX7, LPY9); + setParagraphGap(LPX14, LPY14); + setIndentGap(LPX9, LPY9); + setGridCellGap(LPX4, LPY4); + + setMinimumButtonWidth(new UnitValue(75, UnitValue.LPX, null)); + setButtonOrder("L_E+U+YNBXOCAH_R"); + setDialogInsets(LPY11, LPX11, LPY11, LPX11); + setPanelInsets(LPY7, LPX7, LPY7, LPX7); + BASE_DPI = 96; + } else { + setRelatedGap(LPX8, LPY8); + setUnrelatedGap(LPX12, LPY12); + setParagraphGap(LPX16, LPY16); + setIndentGap(LPX10, LPY10); + setGridCellGap(LPX8, LPY8); + + setMinimumButtonWidth(new UnitValue(68, UnitValue.LPX, null)); + setButtonOrder("L_HE+U+NYBXCOA_R"); + setDialogInsets(LPY14, LPX20, LPY20, LPX20); + setPanelInsets(LPY16, LPX16, LPY16, LPX16); + BASE_DPI = 72; + } + } + + /** Returns the current platform + * @return <code>PlatformDefaults.WINDOWS</code> or <code>PlatformDefaults.MAC_OSX</code> + */ + public static int getPlatform() + { + return CUR_PLAF; + } + + public static int getDefaultDPI() + { + return BASE_DPI; + } + + /** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied + * with. If <code>null</code> this will default to a scale that will scale the current screen to the default screen resolution + * (72 DPI for Mac and 92 DPI for Windows). + * @return The forced scale or <code>null</code> for default scaling. + * @see #getHorizontalScaleFactor() + * @see ComponentWrapper#getHorizontalScreenDPI() + */ + public static Float + getHorizontalScaleFactor() + { + return horScale; + } + + /** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied + * with. If <code>null</code> this will default to a scale that will scale the current screen to the default screen resolution + * (72 DPI for Mac and 92 DPI for Windows). + * @param f The forced scale or <code>null</code> for default scaling. + * @see #getHorizontalScaleFactor() + * @see ComponentWrapper#getHorizontalScreenDPI() + */ + public static void setHorizontalScaleFactor(Float f) + { + if (horScale != f) { + horScale = f; + MOD_COUNT++; + } + } + + /** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied + * with. If <code>null</code> this will default to a scale that will scale the current screen to the default screen resolution + * (72 DPI for Mac and 92 DPI for Windows). + * @return The forced scale or <code>null</code> for default scaling. + * @see #getHorizontalScaleFactor() + * @see ComponentWrapper#getVerticalScreenDPI() + */ + public static Float getVerticalScaleFactor() + { + return verScale; + } + + /** The forced scale factor that all screen relative units (e.g. millimeters, inches and logical pixels) will be multiplied + * with. If <code>null</code> this will default to a scale that will scale the current screen to the default screen resolution + * (72 DPI for Mac and 92 DPI for Windows). + * @param f The forced scale or <code>null</code> for default scaling. + * @see #getHorizontalScaleFactor() + * @see ComponentWrapper#getVerticalScreenDPI() + */ + public static void setVerticalScaleFactor(Float f) + { + if (verScale != f) { + verScale = f; + MOD_COUNT++; + } + } + + /** What base value should be used to calculate logical pixel sizes. + * @return The current base. Default is {@link #BASE_SCALE_FACTOR} + * @see #BASE_FONT_SIZE + * @see # BASE_SCREEN_DPI_FACTOR + * @see #BASE_REAL_PIXEL + */ + public static int getLogicalPixelBase() + { + return LP_BASE; + } + + /** What base value should be used to calculate logical pixel sizes. + * @param base The new base. Default is {@link #BASE_SCALE_FACTOR} + * @see #BASE_FONT_SIZE + * @see # BASE_SCREEN_DPI_FACTOR + * @see #BASE_REAL_PIXEL + */ + public static void setLogicalPixelBase(int base) + { + if (LP_BASE != base) { + if (base < BASE_FONT_SIZE || base > BASE_SCALE_FACTOR) + throw new IllegalArgumentException("Unrecognized base: " + base); + + LP_BASE = base; + MOD_COUNT++; + } + } + + /** Sets gap value for components that are "related". + * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change. + * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change. + */ + public static void setRelatedGap(UnitValue x, UnitValue y) + { + setUnitValue(new String[] {"r", "rel", "related"}, x, y); + + RELATED_X = new BoundSize(x, x, null, "rel:rel"); + RELATED_Y = new BoundSize(y, y, null, "rel:rel"); + } + + /** Sets gap value for components that are "unrelated". + * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change. + * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change. + */ + public static void setUnrelatedGap(UnitValue x, UnitValue y) + { + setUnitValue(new String[] {"u", "unrel", "unrelated"}, x, y); + + UNRELATED_X = new BoundSize(x, x, null, "unrel:unrel"); + UNRELATED_Y = new BoundSize(y, y, null, "unrel:unrel"); + } + + /** Sets paragraph gap value for components. + * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change. + * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change. + */ + public static void setParagraphGap(UnitValue x, UnitValue y) + { + setUnitValue(new String[] {"p", "para", "paragraph"}, x, y); + } + + /** Sets gap value for components that are "intended". + * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change. + * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change. + */ + public static void setIndentGap(UnitValue x, UnitValue y) + { + setUnitValue(new String[] {"i", "ind", "indent"}, x, y); + } + + /** Sets gap between two cells in the grid. Note that this is not a gap between component IN a cell, that has to be set + * on the component constraints. The value will be the min and preferred size of the gap. + * @param x The value that will be transformed to pixels. If <code>null</code> the current value will not change. + * @param y The value that will be transformed to pixels. If <code>null</code> the current value will not change. + */ + public static void setGridCellGap(UnitValue x, UnitValue y) + { + if (x != null) + DEF_HGAP = new BoundSize(x, x, null, null); + + if (y != null) + DEF_VGAP = new BoundSize(y, y, null, null); + + MOD_COUNT++; + } + + /** Sets the recommended minimum button width. + * @param width The recommended minimum button width. + */ + public static void setMinimumButtonWidth(UnitValue width) + { + BUTT_WIDTH = width; + MOD_COUNT++; + } + + /** Returns the recommended minimum button width depending on the current set platform. + * @return The recommended minimum button width depending on the current set platform. + */ + public static UnitValue getMinimumButtonWidth() + { + return BUTT_WIDTH; + } + + /** Returns the unit value associated with the unit. (E.i. "related" or "indent"). Must be lower case. + * @param unit The unit string. + * @return Tthe unit value associated with the unit. <code>null</code> for unrecognized units. + */ + public static UnitValue getUnitValueX(String unit) + { + return HOR_DEFS.get(unit); + } + + /** Returns the unit value associated with the unit. (E.i. "related" or "indent"). Must be lower case. + * @param unit The unit string. + * @return Tthe unit value associated with the unit. <code>null</code> for unrecognized units. + */ + public static UnitValue getUnitValueY(String unit) + { + return VER_DEFS.get(unit); + } + + /** Sets the unit value assiciated with a unit string. This may be used to store values for new unit strings + * or modify old. Note that if a built in unit (such as "related") is modified all versions of it must be + * set (I.e. "r", "rel" and "related"). The build in values will be reset to the default ones if the platform + * is re-set. + * @param unitStrings The unit strings. E.g. "mu", "myunit". Will be converted to lower case and trimmed. Not <code>null</code>. + * @param x The value for the horizontal dimension. If <code>null</code> the value is not changed. + * @param y The value for the vertical dimension. Might be same object as for <code>x</code>. If <code>null</code> the value is not changed. + */ + public static final void setUnitValue(String[] unitStrings, UnitValue x, UnitValue y) + { + for (int i = 0; i < unitStrings.length; i++) { + String s = unitStrings[i].toLowerCase().trim(); + if (x != null) + HOR_DEFS.put(s, x); + if (y != null) + VER_DEFS.put(s, y); + } + MOD_COUNT++; + } + + /** Understands ("r", "rel", "related") OR ("u", "unrel", "unrelated") OR ("i", "ind", "indent") OR ("p", "para", "paragraph"). + */ + static final int convertToPixels(float value, String unit, boolean isHor, float ref, ContainerWrapper parent, ComponentWrapper comp) + { + UnitValue uv = (isHor ? HOR_DEFS : VER_DEFS).get(unit); + return uv != null ? Math.round(value * uv.getPixels(ref, parent, comp)) : UnitConverter.UNABLE; + } + + /** Returns the order for the typical buttons in a standard button bar. It is one letter per button type. + * @return The button order. + * @see #setButtonOrder(String) + */ + public static final String getButtonOrder() + { + return BUTTON_FORMAT; + } + + /** Sets the order for the typical buttons in a standard button bar. It is one letter per button type. + * <p> + * Letter in upper case will get the minimum button width that the {@link #getMinimumButtonWidth()} specifies + * and letters in lower case will get the width the corrent look&feel specifies. + * <p> + * Gaps will never be added to before the first component or after the last component. However, '+' (push) will be + * applied before and after as well, but with a minimum size of 0 if first/last so there will not be a gap + * before or after. + * <p> + * If gaps are explicitly set on buttons they will never be reduced, but they may be increased. + * <p> + * These are the characters that can be used: + * <ul> + * <li><code>'L'</code> - Buttons with this style tag will staticall end up on the left end of the bar. + * <li><code>'R'</code> - Buttons with this style tag will staticall end up on the right end of the bar. + * <li><code>'H'</code> - A tag for the "help" button that normally is supposed to be on the right. + * <li><code>'E'</code> - A tag for the "help2" button that normally is supposed to be on the left. + * <li><code>'Y'</code> - A tag for the "yes" button. + * <li><code>'N'</code> - A tag for the "no" button. + * <li><code>'X'</code> - A tag for the "next >" or "forward >" button. + * <li><code>'B'</code> - A tag for the "< back>" or "< previous" button. + * <li><code>'I'</code> - A tag for the "finish". + * <li><code>'A'</code> - A tag for the "apply" button. + * <li><code>'C'</code> - A tag for the "cancel" or "close" button. + * <li><code>'O'</code> - A tag for the "ok" or "done" button. + * <li><code>'U'</code> - All Uncategorized, Other, or "Unknown" buttons. Tag will be "other". + * <li><code>'+'</code> - A glue push gap that will take as much space as it can and at least an "unrelated" gap. (Platform dependant) + * <li><code>'_'</code> - (underscore) An "unrelated" gap. (Platform dependant) + * </ul> + * <p> + * Even though the style tags are normally applied to buttons this works with all components. + * <p> + * The normal style for MAC OS X is <code>"L_HE+U+FBI_NYCOA_R"</code> and for Windows is <code>"L_E+U+FBI_YNOCAH_R"</code> + * @param order The new button order for the current platform. + */ + public static final void setButtonOrder(String order) + { + BUTTON_FORMAT = order; + MOD_COUNT++; + } + + /** Returns the tag (used in the {@link CC}) for a char. The char is same as used in {@link #getButtonOrder()}. + * @param c The char. Must be lower case! + * @return The tag that corresponds to the char or <code>null</code> if the char is unrecognized. + */ + static final String getTagForChar(char c) + { + switch (c) { + case 'o': + return "ok"; + case 'c': + return "cancel"; + case 'h': + return "help"; + case 'e': + return "help2"; + case 'y': + return "yes"; + case 'n': + return "no"; + case 'a': + return "apply"; + case 'x': + return "next"; // a.k.a forward + case 'b': + return "back"; // a.k.a. previous + case 'i': + return "finish"; + case 'l': + return "left"; + case 'r': + return "right"; + case 'u': + return "other"; + default: + return null; + } + } + + /** Returns the platform recommended inter-cell gap in the horizontal (x) dimension.. + * @return The platform recommended inter-cell gap in the horizontal (x) dimension.. + */ + public static BoundSize getGridGapX() + { + return DEF_HGAP; + } + + /** Returns the platform recommended inter-cell gap in the vertical (x) dimension.. + * @return The platform recommended inter-cell gap in the vertical (x) dimension.. + */ + public static BoundSize getGridGapY() + { + return DEF_VGAP; + } + + /** Returns the default dialog inset depending of the current platform. + * @param side top == 0, left == 1, bottom = 2, right = 3. + * @return The inset. Never <code>null</code>. + */ + public static UnitValue getDialogInsets(int side) + { + return DIALOG_INS[side]; + } + + /** Sets the default insets for a dialog. Values that are null will not be changed. + * @param top The top inset. May be <code>null</code>. + * @param left The left inset. May be <code>null</code>. + * @param bottom The bottom inset. May be <code>null</code>. + * @param right The right inset. May be <code>null</code>. + */ + public static void setDialogInsets(UnitValue top, UnitValue left, UnitValue bottom, UnitValue right) + { + if (top != null) + DIALOG_INS[0] = top; + if (left != null) + DIALOG_INS[1] = left; + if (bottom != null) + DIALOG_INS[2] = bottom; + if (right != null) + DIALOG_INS[3] = right; + + MOD_COUNT++; + } + + /** Returns the default panel inset depending of the current platform. + * @param side top == 0, left == 1, bottom = 2, right = 3. + * @return The inset. Never <code>null</code>. + */ + public static UnitValue getPanelInsets(int side) + { + return PANEL_INS[side]; + } + + /** Sets the default insets for a dialog. Values that are null will not be changed. + * @param top The top inset. May be <code>null</code>. + * @param left The left inset. May be <code>null</code>. + * @param bottom The bottom inset. May be <code>null</code>. + * @param right The right inset. May be <code>null</code>. + */ + public static void setPanelInsets(UnitValue top, UnitValue left, UnitValue bottom, UnitValue right) + { + if (top != null) + PANEL_INS[0] = top; + + if (left != null) + PANEL_INS[1] = left; + + if (bottom != null) + PANEL_INS[2] = bottom; + + if (right != null) + PANEL_INS[3] = right; + + MOD_COUNT++; + } + + /** Returns the percentage used for alignment for labels (0 is left, 50 is center and 100 is right). + * @return The percentage used for alignment for labels + */ + public static float getLabelAlignPercentage() + { + return CUR_PLAF == MAC_OSX ? 1f : 0f; + } + + /** Returns the default gap between two components that <b>are in the same cell</b>. + * @param comp The component that the gap is for. Never <code>null</code>. + * @param adjacentComp The adjacent component if any. May be <code>null</code>. + * @param adjacentSide What side the <code>adjacentComp</code> is on. {@link javax.swing.SwingUtilities#TOP} or + * {@link javax.swing.SwingUtilities#LEFT} or {@link javax.swing.SwingUtilities#BOTTOM} or {@link javax.swing.SwingUtilities#RIGHT}. + * @param tag The tag string that the component might be tagged with in the component constraints. May be <code>null</code>. + * @param isLTR If it is left-to-right. + * @return The default gap between two components or <code>null</code> if there should be no gap. + */ + static BoundSize getDefaultComponentGap(ComponentWrapper comp, ComponentWrapper adjacentComp, int adjacentSide, String tag, boolean isLTR) + { + if (GAP_PROVIDER != null) + return GAP_PROVIDER.getDefaultGap(comp, adjacentComp, adjacentSide, tag, isLTR); + + if (adjacentComp == null) + return null; + +// if (adjacentComp == null || adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.TOP) +// return null; + + return (adjacentSide == SwingConstants.LEFT || adjacentSide == SwingConstants.RIGHT) ? RELATED_X : RELATED_Y; + } + + /** Returns the current gap privider or <code>null</code> if none is set and "related" should always be used. + * @return The current gap privider or <code>null</code> if none is set and "related" should always be used. + */ + public static InCellGapProvider getGapProvider() + { + return GAP_PROVIDER; + } + + /** Sets the current gap privider or <code>null</code> if none is set and "related" should always be used. + * @param provider The current gap privider or <code>null</code> if none is set and "related" should always be used. + */ + public static void setGapProvider(InCellGapProvider provider) + { + GAP_PROVIDER = provider; + } + + /** Returns how many times the defaults has been changed. This can be used as a light weight check to + * see if layout caches needs to be refreshed. + * @return How many times the defaults has been changed. + */ + public static int getModCount() + { + return MOD_COUNT; + } + + /** Tells all layout manager instances to revalidate and recalculated everything. + */ + public void invalidate() + { + MOD_COUNT++; + } + + /** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10". + * @return The current default unit. + * @see UnitValue#PIXEL + * @see UnitValue#LPX + */ + public final static int getDefaultHorizontalUnit() + { + return DEF_H_UNIT; + } + + /** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10". + * @param unit The new default unit. + * @see UnitValue#PIXEL + * @see UnitValue#LPX + */ + public final static void setDefaultHorizontalUnit(int unit) + { + if (unit < UnitValue.PIXEL || unit > UnitValue.LABEL_ALIGN) + throw new IllegalArgumentException("Illegal Unit: " + unit); + + if (DEF_H_UNIT != unit) { + DEF_H_UNIT = unit; + MOD_COUNT++; + } + } + + /** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10". + * @return The current default unit. + * @see UnitValue#PIXEL + * @see UnitValue#LPY + */ + public final static int getDefaultVerticalUnit() + { + return DEF_V_UNIT; + } + + /** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10". + * @param unit The new default unit. + * @see UnitValue#PIXEL + * @see UnitValue#LPY + */ + public final static void setDefaultVerticalUnit(int unit) + { + if (unit < UnitValue.PIXEL || unit > UnitValue.LABEL_ALIGN) + throw new IllegalArgumentException("Illegal Unit: " + unit); + + if (DEF_V_UNIT != unit) { + DEF_V_UNIT = unit; + MOD_COUNT++; + } + } }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/layout/ResizeConstraint.java b/prototypes/miglayout/net/miginfocom/layout/ResizeConstraint.java index 75a4c376..c02ad0f8 100644 --- a/prototypes/miglayout/net/miginfocom/layout/ResizeConstraint.java +++ b/prototypes/miglayout/net/miginfocom/layout/ResizeConstraint.java @@ -1,92 +1,92 @@ -package net.miginfocom.layout;
-
-import java.io.*;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/** A parsed constraint that specifies how an entity (normally column/row or component) can shrink or
- * grow compared to other entities.
- */
-final class ResizeConstraint implements Externalizable
-{
- static final Float WEIGHT_100 = new Float(100);
-
- /** How flexilble the entity should be, relative to other entities, when it comes to growing. <code>null</code> or
- * zero mean it will never grow. An entity that has twise the growWeight compared to another entity will get twice
- * as much of available space.
- * <p>
- * "grow" are only compared within the same "growPrio".
- */
- Float grow = null;
-
- /** The relative priority used for determining which entities gets the extra space first.
- */
- int growPrio = 100;
-
- Float shrink = WEIGHT_100;
-
- int shrinkPrio = 100;
-
- public ResizeConstraint() // For Externalizable
- {
- }
-
- ResizeConstraint(int shrinkPrio, Float shrinkWeight, int growPrio, Float growWeight)
- {
- this.shrinkPrio = shrinkPrio;
- this.shrink = shrinkWeight;
- this.growPrio = growPrio;
- this.grow = growWeight;
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
-
- public void writeExternal(ObjectOutput out) throws IOException
- {
- if (getClass() == ResizeConstraint.class)
- LayoutUtil.writeAsXML(out, this);
- }
-}
+package net.miginfocom.layout; + +import java.io.*; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** A parsed constraint that specifies how an entity (normally column/row or component) can shrink or + * grow compared to other entities. + */ +final class ResizeConstraint implements Externalizable +{ + static final Float WEIGHT_100 = new Float(100); + + /** How flexilble the entity should be, relative to other entities, when it comes to growing. <code>null</code> or + * zero mean it will never grow. An entity that has twise the growWeight compared to another entity will get twice + * as much of available space. + * <p> + * "grow" are only compared within the same "growPrio". + */ + Float grow = null; + + /** The relative priority used for determining which entities gets the extra space first. + */ + int growPrio = 100; + + Float shrink = WEIGHT_100; + + int shrinkPrio = 100; + + public ResizeConstraint() // For Externalizable + { + } + + ResizeConstraint(int shrinkPrio, Float shrinkWeight, int growPrio, Float growWeight) + { + this.shrinkPrio = shrinkPrio; + this.shrink = shrinkWeight; + this.growPrio = growPrio; + this.grow = growWeight; + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + if (getClass() == ResizeConstraint.class) + LayoutUtil.writeAsXML(out, this); + } +} diff --git a/prototypes/miglayout/net/miginfocom/layout/UnitConverter.java b/prototypes/miglayout/net/miginfocom/layout/UnitConverter.java index e94e82bd..3a03ea2a 100644 --- a/prototypes/miglayout/net/miginfocom/layout/UnitConverter.java +++ b/prototypes/miglayout/net/miginfocom/layout/UnitConverter.java @@ -1,59 +1,59 @@ -package net.miginfocom.layout;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-/**
- */
-public abstract class UnitConverter
-{
- /** Value to return if this converter can not handle the <code>unit</code> sent in as an argument
- * to the convert method.
- */
- public static final int UNABLE = -87654312;
-
- /** Converts <code>value</code> to pixels.
- * @param value The value to be converted.
- * @param unit The unit of <code>value</code>. Never <code>null</code> and at least one character.
- * @param refValue Some reference value that may of may not be used. If the unit is percent for instance this value
- * is the value to take the percent from. Usually the size of the parent component in the appropriate dimension.
- * @param isHor If the value is horizontal (<code>true</code>) or vertical (<code>false</code>).
- * @param parent The parent of the target component that <code>value</code> is to be applied to.
- * Might for instance be needed to get the screen that the component is on in a multi screen environment.
- * <p>
- * May be <code>null</code> in which case a "best guess" value should be returned.
- * @param comp The component, if applicable, or <code>null</code> if none.
- * @return The number of pixels if <code>unit</code> is handled by this converter, <code>UnitConverter.UNABLE</code> if not.
- */
- public abstract int convertToPixels(float value, String unit, boolean isHor, float refValue, ContainerWrapper parent, ComponentWrapper comp);
-}
+package net.miginfocom.layout; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +/** + */ +public abstract class UnitConverter +{ + /** Value to return if this converter can not handle the <code>unit</code> sent in as an argument + * to the convert method. + */ + public static final int UNABLE = -87654312; + + /** Converts <code>value</code> to pixels. + * @param value The value to be converted. + * @param unit The unit of <code>value</code>. Never <code>null</code> and at least one character. + * @param refValue Some reference value that may of may not be used. If the unit is percent for instance this value + * is the value to take the percent from. Usually the size of the parent component in the appropriate dimension. + * @param isHor If the value is horizontal (<code>true</code>) or vertical (<code>false</code>). + * @param parent The parent of the target component that <code>value</code> is to be applied to. + * Might for instance be needed to get the screen that the component is on in a multi screen environment. + * <p> + * May be <code>null</code> in which case a "best guess" value should be returned. + * @param comp The component, if applicable, or <code>null</code> if none. + * @return The number of pixels if <code>unit</code> is handled by this converter, <code>UnitConverter.UNABLE</code> if not. + */ + public abstract int convertToPixels(float value, String unit, boolean isHor, float refValue, ContainerWrapper parent, ComponentWrapper comp); +} diff --git a/prototypes/miglayout/net/miginfocom/layout/UnitValue.java b/prototypes/miglayout/net/miginfocom/layout/UnitValue.java index aa12ac3e..e4da114e 100644 --- a/prototypes/miglayout/net/miginfocom/layout/UnitValue.java +++ b/prototypes/miglayout/net/miginfocom/layout/UnitValue.java @@ -1,626 +1,626 @@ -package net.miginfocom.layout;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-import java.beans.Encoder;
-import java.beans.Expression;
-import java.beans.PersistenceDelegate;
-import java.io.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public final class UnitValue implements Serializable
-{
- private static final HashMap<String, Integer> UNIT_MAP = new HashMap<String, Integer>(32);
-
- private static final ArrayList<UnitConverter> CONVERTERS = new ArrayList<UnitConverter>();
-
- /** An operation indicating a static value.
- */
- public static final int STATIC = 100;
-
- /** An operation indicating a addition of two sub units.
- */
- public static final int ADD = 101; // Must have "sub-unit values"
-
- /** An operation indicating a subtraction of two sub units
- */
- public static final int SUB = 102; // Must have "sub-unit values"
-
- /** An operation indicating a multiplication of two sub units.
- */
- public static final int MUL = 103; // Must have "sub-unit values"
-
- /** An operation indicating a division of two sub units.
- */
- public static final int DIV = 104; // Must have "sub-unit values"
-
- /** An operation indicating the minimum of two sub units
- */
- public static final int MIN = 105; // Must have "sub-unit values"
-
- /** An operation indicating the maximum of two sub units
- */
- public static final int MAX = 106; // Must have "sub-unit values"
-
- /** An operation indicating the middle value of two sub units
- */
- public static final int MID = 107; // Must have "sub-unit values"
-
-
-
-
- /** A unit indicating pixels.
- */
- public static final int PIXEL = 0;
-
- /** A unit indicating logical horizontal pixels.
- */
- public static final int LPX = 1;
-
- /** A unit indicating logical vertical pixels.
- */
- public static final int LPY = 2;
-
- /** A unit indicating millimeters.
- */
- public static final int MM = 3;
-
- /** A unit indicating centimeters.
- */
- public static final int CM = 4;
-
- /** A unit indicating inches.
- */
- public static final int INCH = 5;
-
- /** A unit indicating percent.
- */
- public static final int PERCENT = 6;
-
- /** A unit indicating points.
- */
- public static final int PT = 7;
-
- /** A unit indicating screen width in pixels.
- */
- public static final int SPX = 8;
-
- /** A unit indicating screen height in pixels.
- */
- public static final int SPY = 9;
-
- /** A unit indicating alignment.
- */
- public static final int ALIGN = 12;
-
- /** A unit indicating minimum size.
- */
- public static final int MIN_SIZE = 13;
-
- /** A unit indicating preferred size.
- */
- public static final int PREF_SIZE = 14;
-
- /** A unit indicating maximum size.
- */
- public static final int MAX_SIZE = 15;
-
- /** A unit indicating botton size.
- */
- public static final int BUTTON = 16;
-
- /** A unit indicating linking to x.
- */
- public static final int LINK_X = 18; // First link
-
- /** A unit indicating linking to y.
- */
- public static final int LINK_Y = 19;
-
- /** A unit indicating linking to width.
- */
- public static final int LINK_W = 20;
-
- /** A unit indicating linking to height.
- */
- public static final int LINK_H = 21;
-
- /** A unit indicating linking to x2.
- */
- public static final int LINK_X2 = 22;
-
- /** A unit indicating linking to y2.
- */
- public static final int LINK_Y2 = 23;
-
- /** A unit indicating linking to x position on screen.
- */
- public static final int LINK_XPOS = 24;
-
- /** A unit indicating linking to y position on screen.
- */
- public static final int LINK_YPOS = 25; // Last link
-
- /** A unit indicating a lookup.
- */
- public static final int LOOKUP = 26;
-
- /** A unit indicating label alignment.
- */
- public static final int LABEL_ALIGN = 27;
-
- private static final int IDENTITY = -1;
-
- static {
- UNIT_MAP.put("px", new Integer(PIXEL));
- UNIT_MAP.put("lpx", new Integer(LPX));
- UNIT_MAP.put("lpy", new Integer(LPY));
- UNIT_MAP.put("%", new Integer(PERCENT));
- UNIT_MAP.put("cm", new Integer(CM));
- UNIT_MAP.put("in", new Integer(INCH));
- UNIT_MAP.put("spx", new Integer(SPX));
- UNIT_MAP.put("spy", new Integer(SPY));
- UNIT_MAP.put("al", new Integer(ALIGN));
- UNIT_MAP.put("mm", new Integer(MM));
- UNIT_MAP.put("pt", new Integer(PT));
- UNIT_MAP.put("min", new Integer(MIN_SIZE));
- UNIT_MAP.put("minimum", new Integer(MIN_SIZE));
- UNIT_MAP.put("p", new Integer(PREF_SIZE));
- UNIT_MAP.put("pref", new Integer(PREF_SIZE));
- UNIT_MAP.put("max", new Integer(MAX_SIZE));
- UNIT_MAP.put("maximum", new Integer(MAX_SIZE));
- UNIT_MAP.put("button", new Integer(BUTTON));
- UNIT_MAP.put("label", new Integer(LABEL_ALIGN));
- }
-
- static final UnitValue ZERO = new UnitValue(0, null, PIXEL, true, STATIC, null, null, "0px");
- static final UnitValue TOP = new UnitValue(0, null, PERCENT, false, STATIC, null, null, "top");
- static final UnitValue LEADING = new UnitValue(0, null, PERCENT, true, STATIC, null, null, "leading");
- static final UnitValue LEFT = new UnitValue(0, null, PERCENT, true, STATIC, null, null, "left");
- static final UnitValue CENTER = new UnitValue(50, null, PERCENT, true, STATIC, null, null, "center");
- static final UnitValue TRAILING = new UnitValue(100, null, PERCENT, true, STATIC, null, null, "trailing");
- static final UnitValue RIGHT = new UnitValue(100, null, PERCENT, true, STATIC, null, null, "right");
- static final UnitValue BOTTOM = new UnitValue(100, null, PERCENT, false, STATIC, null, null, "bottom");
- static final UnitValue LABEL = new UnitValue(0, null, LABEL_ALIGN, false, STATIC, null, null, "label");
-
- static final UnitValue INF = new UnitValue(LayoutUtil.INF, null, PIXEL, true, STATIC, null, null, "inf");
-
- static final UnitValue BASELINE_IDENTITY = new UnitValue(0, null, IDENTITY, false, STATIC, null, null, "baseline");
-
- private final transient float value;
- private final transient int unit;
- private final transient int oper;
- private final transient String unitStr;
- private final transient boolean isHor;
- private final transient UnitValue[] subUnits;
-
- // Pixel
- public UnitValue(float value) // If hor/ver does not matter.
- {
- this(value, null, PIXEL, true, STATIC, null, null, value + "px");
- }
-
- public UnitValue(float value, int unit, String createString) // If hor/ver does not matter.
- {
- this(value, null, unit, true, STATIC, null, null, createString);
- }
-
- UnitValue(float value, String unitStr, boolean isHor, int oper, String createString)
- {
- this(value, unitStr, -1, isHor, oper, null, null, createString);
- }
-
- UnitValue(boolean isHor, int oper, UnitValue sub1, UnitValue sub2, String createString)
- {
- this(0, "", -1, isHor, oper, sub1, sub2, createString);
- if (sub1 == null || sub2 == null)
- throw new IllegalArgumentException("Sub units is null!");
- }
-
- private UnitValue(float value, String unitStr, int unit, boolean isHor, int oper, UnitValue sub1, UnitValue sub2, String createString)
- {
- if (oper < STATIC || oper > MID)
- throw new IllegalArgumentException("Unknown Operation: " + oper);
-
- if (oper >= ADD && oper <= MID && (sub1 == null || sub2 == null))
- throw new IllegalArgumentException(oper + " Operation may not have null sub-UnitValues.");
-
- this.value = value;
- this.oper = oper;
- this.isHor = isHor;
- this.unitStr = unitStr;
- this.unit = unitStr != null ? parseUnitString() : unit;
- this.subUnits = sub1 != null && sub2 != null ? new UnitValue[] {sub1, sub2} : null;
-
- LayoutUtil.putCCString(this, createString); // "this" escapes!! Safe though.
- }
-
- /** Returns the size in pixels rounded.
- * @param refValue The reference value. Normally the size of the parent. For unit {@link #ALIGN} the current size of the component should be sent in.
- * @param parent The parent. May be <code>null</code> for testing the validity of the value, but should normally not and are not
- * required to return any usable value if <code>null</code>.
- * @param comp The component, if any, that the value is for. Might be <code>null</code> if the value is not
- * connected to any component.
- * @return The size in pixels.
- */
- public final int getPixels(float refValue, ContainerWrapper parent, ComponentWrapper comp)
- {
- return Math.round(getPixelsExact(refValue, parent, comp));
- }
-
- private static final float[] SCALE = new float[] {25.4f, 2.54f, 1f, 0f, 72f};
- /** Returns the size in pixels.
- * @param refValue The reference value. Normally the size of the parent. For unit {@link #ALIGN} the current size of the component should be sent in.
- * @param parent The parent. May be <code>null</code> for testing the validity of the value, but should normally not and are not
- * required to return any usable value if <code>null</code>.
- * @param comp The component, if any, that the value is for. Might be <code>null</code> if the value is not
- * connected to any component.
- * @return The size in pixels.
- */
- public final float getPixelsExact(float refValue, ContainerWrapper parent, ComponentWrapper comp)
- {
- if (parent == null)
- return 1;
-
- if (oper == STATIC) {
- switch (unit) {
- case PIXEL:
- return value;
-
- case LPX:
- case LPY:
- return parent.getPixelUnitFactor(unit == LPX) * value;
-
- case MM:
- case CM:
- case INCH:
- case PT:
- float f = SCALE[unit - MM];
- Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor();
- if (s != null)
- f *= s.floatValue();
- return (isHor ? parent.getHorizontalScreenDPI() : parent.getVerticalScreenDPI()) * value / f;
-
- case PERCENT:
- return value * refValue * 0.01f;
-
- case SPX:
- case SPY:
- return (unit == SPX ? parent.getScreenWidth() : parent.getScreenHeight()) * value * 0.01f;
-
- case ALIGN:
- Integer st = LinkHandler.getValue(parent.getLayout(), "visual", isHor ? LinkHandler.X : LinkHandler.Y);
- Integer sz = LinkHandler.getValue(parent.getLayout(), "visual", isHor ? LinkHandler.WIDTH : LinkHandler.HEIGHT);
- if (st == null || sz == null)
- return 0;
- return value * (Math.max(0, sz.intValue()) - refValue) + st.intValue();
-
- case MIN_SIZE:
- if (comp == null)
- return 0;
- return isHor ? comp.getMinimumWidth() : comp.getMinimumHeight();
-
- case PREF_SIZE:
- if (comp == null)
- return 0;
- return isHor ? comp.getPreferredWidth() : comp.getPreferredHeight();
-
- case MAX_SIZE:
- if (comp == null)
- return 0;
- return isHor ? comp.getMaximumWidth() : comp.getMaximumHeight();
-
- case BUTTON:
- return PlatformDefaults.getMinimumButtonWidth().getPixels(refValue, parent, comp);
-
- case LINK_X:
- case LINK_Y:
- case LINK_W:
- case LINK_H:
- case LINK_X2:
- case LINK_Y2:
- case LINK_XPOS:
- case LINK_YPOS:
- Integer v = LinkHandler.getValue(parent.getLayout(), getLinkTargetId(), unit - (unit >= LINK_XPOS ? LINK_XPOS : LINK_X));
- if (v == null)
- return 0;
-
- if (unit == LINK_XPOS)
- return parent.getScreenLocationX() + v.intValue();
- if (unit == LINK_YPOS)
- return parent.getScreenLocationY() + v.intValue();
-
- return v.intValue();
-
- case LOOKUP:
- float res = lookup(refValue, parent, comp);
- if (res != UnitConverter.UNABLE)
- return res;
-
- case LABEL_ALIGN:
- return PlatformDefaults.getLabelAlignPercentage() * refValue;
-
- case IDENTITY:
- }
- throw new IllegalArgumentException("Unknown/illegal unit: " + unit + ", unitStr: " + unitStr);
- }
-
- if (subUnits != null && subUnits.length == 2) {
- float r1 = subUnits[0].getPixelsExact(refValue, parent, comp);
- float r2 = subUnits[1].getPixelsExact(refValue, parent, comp);
- switch (oper) {
- case ADD:
- return r1 + r2;
- case SUB:
- return r1 - r2;
- case MUL:
- return r1 * r2;
- case DIV:
- return r1 / r2;
- case MIN:
- return r1 < r2 ? r1 : r2;
- case MAX:
- return r1 > r2 ? r1 : r2;
- case MID:
- return (r1 + r2) * 0.5f;
- }
- }
-
- throw new IllegalArgumentException("Internal: Unknown Oper: " + oper);
- }
-
- private final float lookup(float refValue, ContainerWrapper parent, ComponentWrapper comp)
- {
- float res = UnitConverter.UNABLE;
- for (int i = CONVERTERS.size() - 1; i >= 0; i--) {
- res = CONVERTERS.get(i).convertToPixels(value, unitStr, isHor, refValue, parent, comp);
- if (res != UnitConverter.UNABLE)
- return res;
- }
- return PlatformDefaults.convertToPixels(value, unitStr, isHor, refValue, parent, comp);
- }
-
- private final int parseUnitString()
- {
- int len = unitStr.length();
- if (len == 0)
- return isHor ? PlatformDefaults.getDefaultHorizontalUnit() : PlatformDefaults.getDefaultVerticalUnit();
-
- Integer u = UNIT_MAP.get(unitStr);
- if (u != null)
- return u.intValue();
-
- if (unitStr.equals("lp"))
- return isHor ? LPX : LPY;
-
- if (unitStr.equals("sp"))
- return isHor ? SPX : SPY;
-
- if (lookup(0, null, null) != UnitConverter.UNABLE) // To test so we can fail fast
- return LOOKUP;
-
- if (unitStr.endsWith(".x"))
- return LINK_X;
- if (unitStr.endsWith(".y"))
- return LINK_Y;
- if (unitStr.endsWith(".w") || unitStr.endsWith(".width"))
- return LINK_W;
- if (unitStr.endsWith(".h") || unitStr.endsWith(".height"))
- return LINK_H;
- if (unitStr.endsWith(".x2"))
- return LINK_X2;
- if (unitStr.endsWith(".y2"))
- return LINK_Y2;
- if (unitStr.endsWith(".xpos"))
- return LINK_XPOS;
- if (unitStr.endsWith(".ypos"))
- return LINK_YPOS;
-
- throw new IllegalArgumentException("Unknown keyword: " + unitStr);
- }
-
- final boolean isLinked()
- {
- return unit >= LINK_X && unit <= LINK_YPOS;
- }
-
- final boolean isLinkedDeep()
- {
- if (subUnits == null)
- return isLinked();
-
- for (int i = 0; i < subUnits.length; i++) {
- if (subUnits[i].isLinkedDeep())
- return true;
- }
-
- return false;
- }
-
- final String getLinkTargetId()
- {
- return unitStr.substring(0, unitStr.length() - (unit < LINK_X2 ? 2 : (unit > LINK_Y2 ? 5 : 3)));
- }
-
- final UnitValue getSubUnitValue(int i)
- {
- return subUnits[i];
- }
-
- final int getSubUnitCount()
- {
- return subUnits != null ? subUnits.length : 0;
- }
-
- public final UnitValue[] getSubUnits()
- {
- return subUnits;
- }
-
- public final int getUnit()
- {
- return unit;
- }
-
- public final String getUnitString()
- {
- return unitStr;
- }
-
- public final int getOperation()
- {
- return oper;
- }
-
- public final float getValue()
- {
- return value;
- }
-
- public final boolean isHorizontal()
- {
- return isHor;
- }
-
- final public String toString()
- {
- return getClass().getName() + ". Value=" + value + ", unit=" + unit + ", unitString: " + unitStr + ", oper=" + oper + ", isHor: " + isHor;
- }
-
- /** Returns the creation string for this object. Note that {@link LayoutUtil#setDesignTime(ContainerWrapper, boolean)} must be
- * set to <code>true</code> for the creation strings to be stored.
- * @return The constraint string or <code>null</code> if none is registered.
- */
- public final String getConstraintString()
- {
- return LayoutUtil.getCCString(this);
- }
-
- public final int hashCode()
- {
- return (int) (value * 12345) + (oper >>> 5) + unit >>> 17;
- }
-
- /** Adds a global unit converter that can convert from some <code>unit</code> to pixels.
- * <p>
- * This converter will be asked before the platform converter so the values for it (e.g. "related" and "unrelated")
- * can be overridden. It is however not possible to override the built in ones (e.g. "mm", "pixel" or "lp").
- * @param conv The converter. Not <code>null</code>.
- */
- public final synchronized static void addGlobalUnitConverter(UnitConverter conv)
- {
- if (conv == null)
- throw new NullPointerException();
- CONVERTERS.add(conv);
- }
-
- /** Removed the converter.
- * @param unit The converter.
- * @return If there was a converter found and thus removed.
- */
- public final synchronized static boolean removeGlobalUnitConverter(String unit)
- {
- return CONVERTERS.remove(unit);
- }
-
- /** Returns the global converters currently registered. The platform converter will not be in this list.
- * @return The converters. Never <code>null</code>.
- */
- public final synchronized static UnitConverter[] getGlobalUnitConverters()
- {
- return CONVERTERS.toArray(new UnitConverter[CONVERTERS.size()]);
- }
-
- /** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
- * @return The current default unit.
- * @see #PIXEL
- * @see #LPX
- * @deprecated Use {@link PlatformDefaults#getDefaultHorizontalUnit()} and {@link PlatformDefaults#getDefaultVerticalUnit()} instead.
- */
- public final static int getDefaultUnit()
- {
- return PlatformDefaults.getDefaultHorizontalUnit();
- }
-
- /** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10".
- * @param unit The new default unit.
- * @see #PIXEL
- * @see #LPX
- * @deprecated Use {@link PlatformDefaults#setDefaultHorizontalUnit(int)} and {@link PlatformDefaults#setDefaultVerticalUnit(int)} instead.
- */
- public final static void setDefaultUnit(int unit)
- {
- PlatformDefaults.setDefaultHorizontalUnit(unit);
- PlatformDefaults.setDefaultVerticalUnit(unit);
- }
-
- static {
- LayoutUtil.setDelegate(UnitValue.class, new PersistenceDelegate() {
- protected Expression instantiate(Object oldInstance, Encoder out)
- {
- UnitValue uv = (UnitValue) oldInstance;
- String cs = uv.getConstraintString();
- if (cs == null)
- throw new IllegalStateException("Design time must be on to use XML persistence. See LayoutUtil.");
-
- return new Expression(oldInstance, ConstraintParser.class, "parseUnitValueOrAlign", new Object[] {
- uv.getConstraintString(), (uv.isHorizontal() ? Boolean.TRUE : Boolean.FALSE), null
- });
- }
- });
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private static final long serialVersionUID = 1L;
-
- private Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- private void writeObject(ObjectOutputStream out) throws IOException
- {
- if (getClass() == UnitValue.class)
- LayoutUtil.writeAsXML(out, this);
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
+package net.miginfocom.layout; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +import java.beans.Encoder; +import java.beans.Expression; +import java.beans.PersistenceDelegate; +import java.io.*; +import java.util.ArrayList; +import java.util.HashMap; + +public final class UnitValue implements Serializable +{ + private static final HashMap<String, Integer> UNIT_MAP = new HashMap<String, Integer>(32); + + private static final ArrayList<UnitConverter> CONVERTERS = new ArrayList<UnitConverter>(); + + /** An operation indicating a static value. + */ + public static final int STATIC = 100; + + /** An operation indicating a addition of two sub units. + */ + public static final int ADD = 101; // Must have "sub-unit values" + + /** An operation indicating a subtraction of two sub units + */ + public static final int SUB = 102; // Must have "sub-unit values" + + /** An operation indicating a multiplication of two sub units. + */ + public static final int MUL = 103; // Must have "sub-unit values" + + /** An operation indicating a division of two sub units. + */ + public static final int DIV = 104; // Must have "sub-unit values" + + /** An operation indicating the minimum of two sub units + */ + public static final int MIN = 105; // Must have "sub-unit values" + + /** An operation indicating the maximum of two sub units + */ + public static final int MAX = 106; // Must have "sub-unit values" + + /** An operation indicating the middle value of two sub units + */ + public static final int MID = 107; // Must have "sub-unit values" + + + + + /** A unit indicating pixels. + */ + public static final int PIXEL = 0; + + /** A unit indicating logical horizontal pixels. + */ + public static final int LPX = 1; + + /** A unit indicating logical vertical pixels. + */ + public static final int LPY = 2; + + /** A unit indicating millimeters. + */ + public static final int MM = 3; + + /** A unit indicating centimeters. + */ + public static final int CM = 4; + + /** A unit indicating inches. + */ + public static final int INCH = 5; + + /** A unit indicating percent. + */ + public static final int PERCENT = 6; + + /** A unit indicating points. + */ + public static final int PT = 7; + + /** A unit indicating screen width in pixels. + */ + public static final int SPX = 8; + + /** A unit indicating screen height in pixels. + */ + public static final int SPY = 9; + + /** A unit indicating alignment. + */ + public static final int ALIGN = 12; + + /** A unit indicating minimum size. + */ + public static final int MIN_SIZE = 13; + + /** A unit indicating preferred size. + */ + public static final int PREF_SIZE = 14; + + /** A unit indicating maximum size. + */ + public static final int MAX_SIZE = 15; + + /** A unit indicating botton size. + */ + public static final int BUTTON = 16; + + /** A unit indicating linking to x. + */ + public static final int LINK_X = 18; // First link + + /** A unit indicating linking to y. + */ + public static final int LINK_Y = 19; + + /** A unit indicating linking to width. + */ + public static final int LINK_W = 20; + + /** A unit indicating linking to height. + */ + public static final int LINK_H = 21; + + /** A unit indicating linking to x2. + */ + public static final int LINK_X2 = 22; + + /** A unit indicating linking to y2. + */ + public static final int LINK_Y2 = 23; + + /** A unit indicating linking to x position on screen. + */ + public static final int LINK_XPOS = 24; + + /** A unit indicating linking to y position on screen. + */ + public static final int LINK_YPOS = 25; // Last link + + /** A unit indicating a lookup. + */ + public static final int LOOKUP = 26; + + /** A unit indicating label alignment. + */ + public static final int LABEL_ALIGN = 27; + + private static final int IDENTITY = -1; + + static { + UNIT_MAP.put("px", new Integer(PIXEL)); + UNIT_MAP.put("lpx", new Integer(LPX)); + UNIT_MAP.put("lpy", new Integer(LPY)); + UNIT_MAP.put("%", new Integer(PERCENT)); + UNIT_MAP.put("cm", new Integer(CM)); + UNIT_MAP.put("in", new Integer(INCH)); + UNIT_MAP.put("spx", new Integer(SPX)); + UNIT_MAP.put("spy", new Integer(SPY)); + UNIT_MAP.put("al", new Integer(ALIGN)); + UNIT_MAP.put("mm", new Integer(MM)); + UNIT_MAP.put("pt", new Integer(PT)); + UNIT_MAP.put("min", new Integer(MIN_SIZE)); + UNIT_MAP.put("minimum", new Integer(MIN_SIZE)); + UNIT_MAP.put("p", new Integer(PREF_SIZE)); + UNIT_MAP.put("pref", new Integer(PREF_SIZE)); + UNIT_MAP.put("max", new Integer(MAX_SIZE)); + UNIT_MAP.put("maximum", new Integer(MAX_SIZE)); + UNIT_MAP.put("button", new Integer(BUTTON)); + UNIT_MAP.put("label", new Integer(LABEL_ALIGN)); + } + + static final UnitValue ZERO = new UnitValue(0, null, PIXEL, true, STATIC, null, null, "0px"); + static final UnitValue TOP = new UnitValue(0, null, PERCENT, false, STATIC, null, null, "top"); + static final UnitValue LEADING = new UnitValue(0, null, PERCENT, true, STATIC, null, null, "leading"); + static final UnitValue LEFT = new UnitValue(0, null, PERCENT, true, STATIC, null, null, "left"); + static final UnitValue CENTER = new UnitValue(50, null, PERCENT, true, STATIC, null, null, "center"); + static final UnitValue TRAILING = new UnitValue(100, null, PERCENT, true, STATIC, null, null, "trailing"); + static final UnitValue RIGHT = new UnitValue(100, null, PERCENT, true, STATIC, null, null, "right"); + static final UnitValue BOTTOM = new UnitValue(100, null, PERCENT, false, STATIC, null, null, "bottom"); + static final UnitValue LABEL = new UnitValue(0, null, LABEL_ALIGN, false, STATIC, null, null, "label"); + + static final UnitValue INF = new UnitValue(LayoutUtil.INF, null, PIXEL, true, STATIC, null, null, "inf"); + + static final UnitValue BASELINE_IDENTITY = new UnitValue(0, null, IDENTITY, false, STATIC, null, null, "baseline"); + + private final transient float value; + private final transient int unit; + private final transient int oper; + private final transient String unitStr; + private final transient boolean isHor; + private final transient UnitValue[] subUnits; + + // Pixel + public UnitValue(float value) // If hor/ver does not matter. + { + this(value, null, PIXEL, true, STATIC, null, null, value + "px"); + } + + public UnitValue(float value, int unit, String createString) // If hor/ver does not matter. + { + this(value, null, unit, true, STATIC, null, null, createString); + } + + UnitValue(float value, String unitStr, boolean isHor, int oper, String createString) + { + this(value, unitStr, -1, isHor, oper, null, null, createString); + } + + UnitValue(boolean isHor, int oper, UnitValue sub1, UnitValue sub2, String createString) + { + this(0, "", -1, isHor, oper, sub1, sub2, createString); + if (sub1 == null || sub2 == null) + throw new IllegalArgumentException("Sub units is null!"); + } + + private UnitValue(float value, String unitStr, int unit, boolean isHor, int oper, UnitValue sub1, UnitValue sub2, String createString) + { + if (oper < STATIC || oper > MID) + throw new IllegalArgumentException("Unknown Operation: " + oper); + + if (oper >= ADD && oper <= MID && (sub1 == null || sub2 == null)) + throw new IllegalArgumentException(oper + " Operation may not have null sub-UnitValues."); + + this.value = value; + this.oper = oper; + this.isHor = isHor; + this.unitStr = unitStr; + this.unit = unitStr != null ? parseUnitString() : unit; + this.subUnits = sub1 != null && sub2 != null ? new UnitValue[] {sub1, sub2} : null; + + LayoutUtil.putCCString(this, createString); // "this" escapes!! Safe though. + } + + /** Returns the size in pixels rounded. + * @param refValue The reference value. Normally the size of the parent. For unit {@link #ALIGN} the current size of the component should be sent in. + * @param parent The parent. May be <code>null</code> for testing the validity of the value, but should normally not and are not + * required to return any usable value if <code>null</code>. + * @param comp The component, if any, that the value is for. Might be <code>null</code> if the value is not + * connected to any component. + * @return The size in pixels. + */ + public final int getPixels(float refValue, ContainerWrapper parent, ComponentWrapper comp) + { + return Math.round(getPixelsExact(refValue, parent, comp)); + } + + private static final float[] SCALE = new float[] {25.4f, 2.54f, 1f, 0f, 72f}; + /** Returns the size in pixels. + * @param refValue The reference value. Normally the size of the parent. For unit {@link #ALIGN} the current size of the component should be sent in. + * @param parent The parent. May be <code>null</code> for testing the validity of the value, but should normally not and are not + * required to return any usable value if <code>null</code>. + * @param comp The component, if any, that the value is for. Might be <code>null</code> if the value is not + * connected to any component. + * @return The size in pixels. + */ + public final float getPixelsExact(float refValue, ContainerWrapper parent, ComponentWrapper comp) + { + if (parent == null) + return 1; + + if (oper == STATIC) { + switch (unit) { + case PIXEL: + return value; + + case LPX: + case LPY: + return parent.getPixelUnitFactor(unit == LPX) * value; + + case MM: + case CM: + case INCH: + case PT: + float f = SCALE[unit - MM]; + Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor(); + if (s != null) + f *= s.floatValue(); + return (isHor ? parent.getHorizontalScreenDPI() : parent.getVerticalScreenDPI()) * value / f; + + case PERCENT: + return value * refValue * 0.01f; + + case SPX: + case SPY: + return (unit == SPX ? parent.getScreenWidth() : parent.getScreenHeight()) * value * 0.01f; + + case ALIGN: + Integer st = LinkHandler.getValue(parent.getLayout(), "visual", isHor ? LinkHandler.X : LinkHandler.Y); + Integer sz = LinkHandler.getValue(parent.getLayout(), "visual", isHor ? LinkHandler.WIDTH : LinkHandler.HEIGHT); + if (st == null || sz == null) + return 0; + return value * (Math.max(0, sz.intValue()) - refValue) + st.intValue(); + + case MIN_SIZE: + if (comp == null) + return 0; + return isHor ? comp.getMinimumWidth() : comp.getMinimumHeight(); + + case PREF_SIZE: + if (comp == null) + return 0; + return isHor ? comp.getPreferredWidth() : comp.getPreferredHeight(); + + case MAX_SIZE: + if (comp == null) + return 0; + return isHor ? comp.getMaximumWidth() : comp.getMaximumHeight(); + + case BUTTON: + return PlatformDefaults.getMinimumButtonWidth().getPixels(refValue, parent, comp); + + case LINK_X: + case LINK_Y: + case LINK_W: + case LINK_H: + case LINK_X2: + case LINK_Y2: + case LINK_XPOS: + case LINK_YPOS: + Integer v = LinkHandler.getValue(parent.getLayout(), getLinkTargetId(), unit - (unit >= LINK_XPOS ? LINK_XPOS : LINK_X)); + if (v == null) + return 0; + + if (unit == LINK_XPOS) + return parent.getScreenLocationX() + v.intValue(); + if (unit == LINK_YPOS) + return parent.getScreenLocationY() + v.intValue(); + + return v.intValue(); + + case LOOKUP: + float res = lookup(refValue, parent, comp); + if (res != UnitConverter.UNABLE) + return res; + + case LABEL_ALIGN: + return PlatformDefaults.getLabelAlignPercentage() * refValue; + + case IDENTITY: + } + throw new IllegalArgumentException("Unknown/illegal unit: " + unit + ", unitStr: " + unitStr); + } + + if (subUnits != null && subUnits.length == 2) { + float r1 = subUnits[0].getPixelsExact(refValue, parent, comp); + float r2 = subUnits[1].getPixelsExact(refValue, parent, comp); + switch (oper) { + case ADD: + return r1 + r2; + case SUB: + return r1 - r2; + case MUL: + return r1 * r2; + case DIV: + return r1 / r2; + case MIN: + return r1 < r2 ? r1 : r2; + case MAX: + return r1 > r2 ? r1 : r2; + case MID: + return (r1 + r2) * 0.5f; + } + } + + throw new IllegalArgumentException("Internal: Unknown Oper: " + oper); + } + + private final float lookup(float refValue, ContainerWrapper parent, ComponentWrapper comp) + { + float res = UnitConverter.UNABLE; + for (int i = CONVERTERS.size() - 1; i >= 0; i--) { + res = CONVERTERS.get(i).convertToPixels(value, unitStr, isHor, refValue, parent, comp); + if (res != UnitConverter.UNABLE) + return res; + } + return PlatformDefaults.convertToPixels(value, unitStr, isHor, refValue, parent, comp); + } + + private final int parseUnitString() + { + int len = unitStr.length(); + if (len == 0) + return isHor ? PlatformDefaults.getDefaultHorizontalUnit() : PlatformDefaults.getDefaultVerticalUnit(); + + Integer u = UNIT_MAP.get(unitStr); + if (u != null) + return u.intValue(); + + if (unitStr.equals("lp")) + return isHor ? LPX : LPY; + + if (unitStr.equals("sp")) + return isHor ? SPX : SPY; + + if (lookup(0, null, null) != UnitConverter.UNABLE) // To test so we can fail fast + return LOOKUP; + + if (unitStr.endsWith(".x")) + return LINK_X; + if (unitStr.endsWith(".y")) + return LINK_Y; + if (unitStr.endsWith(".w") || unitStr.endsWith(".width")) + return LINK_W; + if (unitStr.endsWith(".h") || unitStr.endsWith(".height")) + return LINK_H; + if (unitStr.endsWith(".x2")) + return LINK_X2; + if (unitStr.endsWith(".y2")) + return LINK_Y2; + if (unitStr.endsWith(".xpos")) + return LINK_XPOS; + if (unitStr.endsWith(".ypos")) + return LINK_YPOS; + + throw new IllegalArgumentException("Unknown keyword: " + unitStr); + } + + final boolean isLinked() + { + return unit >= LINK_X && unit <= LINK_YPOS; + } + + final boolean isLinkedDeep() + { + if (subUnits == null) + return isLinked(); + + for (int i = 0; i < subUnits.length; i++) { + if (subUnits[i].isLinkedDeep()) + return true; + } + + return false; + } + + final String getLinkTargetId() + { + return unitStr.substring(0, unitStr.length() - (unit < LINK_X2 ? 2 : (unit > LINK_Y2 ? 5 : 3))); + } + + final UnitValue getSubUnitValue(int i) + { + return subUnits[i]; + } + + final int getSubUnitCount() + { + return subUnits != null ? subUnits.length : 0; + } + + public final UnitValue[] getSubUnits() + { + return subUnits; + } + + public final int getUnit() + { + return unit; + } + + public final String getUnitString() + { + return unitStr; + } + + public final int getOperation() + { + return oper; + } + + public final float getValue() + { + return value; + } + + public final boolean isHorizontal() + { + return isHor; + } + + final public String toString() + { + return getClass().getName() + ". Value=" + value + ", unit=" + unit + ", unitString: " + unitStr + ", oper=" + oper + ", isHor: " + isHor; + } + + /** Returns the creation string for this object. Note that {@link LayoutUtil#setDesignTime(ContainerWrapper, boolean)} must be + * set to <code>true</code> for the creation strings to be stored. + * @return The constraint string or <code>null</code> if none is registered. + */ + public final String getConstraintString() + { + return LayoutUtil.getCCString(this); + } + + public final int hashCode() + { + return (int) (value * 12345) + (oper >>> 5) + unit >>> 17; + } + + /** Adds a global unit converter that can convert from some <code>unit</code> to pixels. + * <p> + * This converter will be asked before the platform converter so the values for it (e.g. "related" and "unrelated") + * can be overridden. It is however not possible to override the built in ones (e.g. "mm", "pixel" or "lp"). + * @param conv The converter. Not <code>null</code>. + */ + public final synchronized static void addGlobalUnitConverter(UnitConverter conv) + { + if (conv == null) + throw new NullPointerException(); + CONVERTERS.add(conv); + } + + /** Removed the converter. + * @param unit The converter. + * @return If there was a converter found and thus removed. + */ + public final synchronized static boolean removeGlobalUnitConverter(String unit) + { + return CONVERTERS.remove(unit); + } + + /** Returns the global converters currently registered. The platform converter will not be in this list. + * @return The converters. Never <code>null</code>. + */ + public final synchronized static UnitConverter[] getGlobalUnitConverters() + { + return CONVERTERS.toArray(new UnitConverter[CONVERTERS.size()]); + } + + /** Returns the current default unit. The default unit is the unit used if no unit is set. E.g. "width 10". + * @return The current default unit. + * @see #PIXEL + * @see #LPX + * @deprecated Use {@link PlatformDefaults#getDefaultHorizontalUnit()} and {@link PlatformDefaults#getDefaultVerticalUnit()} instead. + */ + public final static int getDefaultUnit() + { + return PlatformDefaults.getDefaultHorizontalUnit(); + } + + /** Sets the default unit. The default unit is the unit used if no unit is set. E.g. "width 10". + * @param unit The new default unit. + * @see #PIXEL + * @see #LPX + * @deprecated Use {@link PlatformDefaults#setDefaultHorizontalUnit(int)} and {@link PlatformDefaults#setDefaultVerticalUnit(int)} instead. + */ + public final static void setDefaultUnit(int unit) + { + PlatformDefaults.setDefaultHorizontalUnit(unit); + PlatformDefaults.setDefaultVerticalUnit(unit); + } + + static { + LayoutUtil.setDelegate(UnitValue.class, new PersistenceDelegate() { + protected Expression instantiate(Object oldInstance, Encoder out) + { + UnitValue uv = (UnitValue) oldInstance; + String cs = uv.getConstraintString(); + if (cs == null) + throw new IllegalStateException("Design time must be on to use XML persistence. See LayoutUtil."); + + return new Expression(oldInstance, ConstraintParser.class, "parseUnitValueOrAlign", new Object[] { + uv.getConstraintString(), (uv.isHorizontal() ? Boolean.TRUE : Boolean.FALSE), null + }); + } + }); + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private static final long serialVersionUID = 1L; + + private Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + private void writeObject(ObjectOutputStream out) throws IOException + { + if (getClass() == UnitValue.class) + LayoutUtil.writeAsXML(out, this); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/swing/MigLayout.java b/prototypes/miglayout/net/miginfocom/swing/MigLayout.java index 7444e9d9..48a6119b 100644 --- a/prototypes/miglayout/net/miginfocom/swing/MigLayout.java +++ b/prototypes/miglayout/net/miginfocom/swing/MigLayout.java @@ -1,549 +1,549 @@ -package net.miginfocom.swing;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-import net.miginfocom.layout.*;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.*;
-import java.util.*;
-
-/** A very flexbile layout manager.
- * <p>
- * Read the documentation that came with this layout manager for information on usage.
- */
-public final class MigLayout implements LayoutManager2, Externalizable
-{
- // ******** Instance part ********
-
- /** The component to string constraints mappings.
- */
- private final Map<Component, Object> scrConstrMap = new IdentityHashMap<Component, Object>(8);
-
- /** Hold the serializable text representation of the constraints.
- */
- private Object layoutConstraints = "", colConstraints = "", rowConstraints = ""; // Should never be null!
-
-
- // ******** Transient part ********
-
- private transient ContainerWrapper cacheParentW = null;
-
- private transient final Map<ComponentWrapper, CC> ccMap = new HashMap<ComponentWrapper, CC>(8);
- private transient javax.swing.Timer debugTimer = null;
-
- private transient LC lc = null;
- private transient AC colSpecs = null, rowSpecs = null;
- private transient Grid grid = null;
- private transient int lastModCount = PlatformDefaults.getModCount();
- private transient int lastHash = -1;
- private transient Dimension lastInvalidSize = null;
-
- private transient ArrayList<LayoutCallback> callbackList = null;
-
- /** Constructor with no constraints.
- */
- public MigLayout()
- {
- this("", "", "");
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "".
- */
- public MigLayout(String layoutConstraints)
- {
- this(layoutConstraints, "", "");
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "".
- * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as "".
- */
- public MigLayout(String layoutConstraints, String colConstraints)
- {
- this(layoutConstraints, colConstraints, "");
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "".
- * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as "".
- * @param rowConstraints The constraints for the rows in the grid. <code>null</code> will be treated as "".
- */
- public MigLayout(String layoutConstraints, String colConstraints, String rowConstraints)
- {
- setLayoutConstraints(layoutConstraints);
- setColumnConstraints(colConstraints);
- setRowConstraints(rowConstraints);
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint.
- */
- public MigLayout(LC layoutConstraints)
- {
- this(layoutConstraints, null, null);
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint.
- * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as an empty constraint.
- */
- public MigLayout(LC layoutConstraints, AC colConstraints)
- {
- this(layoutConstraints, colConstraints, null);
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint.
- * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as an empty constraint.
- * @param rowConstraints The constraints for the rows in the grid. <code>null</code> will be treated as an empty constraint.
- */
- public MigLayout(LC layoutConstraints, AC colConstraints, AC rowConstraints)
- {
- setLayoutConstraints(layoutConstraints);
- setColumnConstraints(colConstraints);
- setRowConstraints(rowConstraints);
- }
-
- /** Returns layout constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in
- * to the constructor or set with {@link #setLayoutConstraints(Object)}.
- * @return The layout constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in
- * to the constructor or set with {@link #setLayoutConstraints(Object)}. Never <code>null</code>.
- */
- public Object getLayoutConstraints()
- {
- return layoutConstraints;
- }
-
- /** Sets the layout constraints for the layout manager instance as a String.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage.
- * @throws RuntimeException if the constaint was not valid.
- */
- public void setLayoutConstraints(Object constr)
- {
- if (constr == null || constr instanceof String) {
- constr = ConstraintParser.prepare((String) constr);
- lc = ConstraintParser.parseLayoutConstraint((String) constr);
- } else if (constr instanceof LC) {
- lc = (LC) constr;
- } else {
- throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString());
- }
- layoutConstraints = constr;
- grid = null;
- }
-
- /** Returns the column layout constraints either as a <code>String</code> or {@link net.miginfocom.layout.AC}.
- * @return The column constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in
- * to the constructor or set with {@link #setLayoutConstraints(Object)}. Never <code>null</code>.
- */
- public Object getColumnConstraints()
- {
- return colConstraints;
- }
-
- /** Sets the column layout constraints for the layout manager instance as a String.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The column layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage.
- * @throws RuntimeException if the constaint was not valid.
- */
- public void setColumnConstraints(Object constr)
- {
- if (constr == null || constr instanceof String) {
- constr = ConstraintParser.prepare((String) constr);
- colSpecs = ConstraintParser.parseColumnConstraints((String) constr);
- } else if (constr instanceof AC) {
- colSpecs = (AC) constr;
- } else {
- throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString());
- }
- colConstraints = constr;
- grid = null;
- }
-
- /** Returns the row layout constraints as a String representation. This string is the exact string as set with {@link #setRowConstraints(Object)}
- * or sent into the constructor.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @return The row layout constraints as a String representation. Never <code>null</code>.
- */
- public Object getRowConstraints()
- {
- return rowConstraints;
- }
-
- /** Sets the row layout constraints for the layout manager instance as a String.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The row layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage.
- * @throws RuntimeException if the constaint was not valid.
- */
- public void setRowConstraints(Object constr)
- {
- if (constr == null || constr instanceof String) {
- constr = ConstraintParser.prepare((String) constr);
- rowSpecs = ConstraintParser.parseRowConstraints((String) constr);
- } else if (constr instanceof AC) {
- rowSpecs = (AC) constr;
- } else {
- throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString());
- }
- rowConstraints = constr;
- grid = null;
- }
-
- /** Returns the component constraints as a String representation. This string is the exact string as set with {@link #setComponentConstraints(java.awt.Component, Object)}
- * or set when adding the component to the parent component.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param comp The component to return the constraints for.
- * @return The component constraints as a String representation ir <code>null</code> if the component is not registered
- * with this layout manager. The returned values is either a String or a {@link net.miginfocom.layout.CC}
- * depending on what constraint was sent in when the component was added. May be <code>null</code>.
- */
- public Object getComponentConstraints(Component comp)
- {
- synchronized(comp.getParent().getTreeLock()) {
- return scrConstrMap.get(comp);
- }
- }
-
- /** Sets the component constraint for the component that already must be handleded by this layout manager.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The component constraints as a String or {@link net.miginfocom.layout.CC}. <code>null</code> is ok.
- * @param comp The component to set the constraints for.
- * @throws RuntimeException if the constaint was not valid.
- * @throws IllegalArgumentException If the component is not handlering the component.
- */
- public void setComponentConstraints(Component comp, Object constr)
- {
- setComponentConstraintsImpl(comp, constr, false);
- }
-
- /** Sets the component constraint for the component that already must be handleded by this layout manager.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The component constraints as a String or {@link net.miginfocom.layout.CC}. <code>null</code> is ok.
- * @param comp The component to set the constraints for.
- * @throws RuntimeException if the constaint was not valid.
- * @throws IllegalArgumentException If the component is not handling the component.
- */
- private void setComponentConstraintsImpl(Component comp, Object constr, boolean noCheck)
- {
- Container parent = comp.getParent();
- synchronized(parent.getTreeLock()) {
- if (noCheck == false && scrConstrMap.containsKey(comp) == false)
- throw new IllegalArgumentException("Component must already be added to parent!");
-
- ComponentWrapper cw = new SwingComponentWrapper(comp);
-
- if (constr == null || constr instanceof String) {
- String cStr = ConstraintParser.prepare((String) constr);
-
- scrConstrMap.put(comp, constr);
- ccMap.put(cw, ConstraintParser.parseComponentConstraint(cStr));
-
- } else if (constr instanceof CC) {
-
- scrConstrMap.put(comp, constr);
- ccMap.put(cw, (CC) constr);
-
- } else {
- throw new IllegalArgumentException("Constraint must be String or ComponentConstraint: " + constr.getClass().toString());
- }
-
- grid = null;
- }
- }
-
- /** Returns if this layout manager is currently managing this component.
- * @param c The component to check. If <code>null</code> then <code>false</code> will be returned.
- * @return If this layout manager is currently managing this component.
- */
- public boolean isManagingComponent(Component c)
- {
- return scrConstrMap.containsKey(c);
- }
-
- /** Adds the callback function that will be called at different stages of the layout cylce.
- * @param callback The callback. Not <code>null</code>.
- */
- public void addLayoutCallback(LayoutCallback callback)
- {
- if (callback == null)
- throw new NullPointerException();
-
- if (callbackList == null)
- callbackList = new ArrayList<LayoutCallback>(1);
-
- callbackList.add(callback);
- }
-
- /** Removes the callback if it exists.
- * @param callback The callback. May be <code>null</code>.
- */
- public void removeLayoutCallback(LayoutCallback callback)
- {
- if (callbackList != null)
- callbackList.remove(callback);
- }
-
- /** Sets the debugging state for this layout manager instance. If debug is turned on a timer will repaint the last laid out parent
- * with debug information on top.
- * <p>
- * Red fill and dashed darked red outline is used to indicate occupied cells in the grid. Blue dashed outline indicate indicate
- * component bounds set.
- * <p>
- * Note that debug can also be set on the layout constraints. There it will be persisted. The calue set here will not. See the class
- * JavaDocs for information.
- * @param b <code>true</code> means debug is turned on.
- */
- private synchronized void setDebug(final ComponentWrapper parentW, boolean b)
- {
- if (b && (debugTimer == null || debugTimer.getDelay() != lc.getDebugMillis())) {
- if (debugTimer != null)
- debugTimer.stop();
-
- ContainerWrapper pCW = parentW.getParent();
- final Component parent = pCW != null ? (Component) pCW.getComponent() : null;
-
- debugTimer = new javax.swing.Timer(lc.getDebugMillis(), new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (grid != null)
- grid.paintDebug();
- }
- });
-
- if (parent != null) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- Container p = parent.getParent();
- if (p != null) {
- if (p instanceof JComponent) {
- ((JComponent) p).revalidate();
- } else {
- parent.invalidate();
- p.validate();
- }
- }
- }
- });
- }
-
- debugTimer.setInitialDelay(100);
- debugTimer.start();
-
- } else if (!b && debugTimer != null) {
- debugTimer.stop();
- debugTimer = null;
- }
- }
-
- /** Returns the current debugging state.
- * @return The current debugging state.
- */
- private boolean getDebug()
- {
- return debugTimer != null;
- }
-
- /** Check if something has changed and if so recrete it to the cached objects.
- * @param parent The parent that is the target for this layout manager.
- */
- private final void checkCache(Container parent)
- {
- if (parent == null)
- return;
-
- // Check if the grid is valid
- int mc = PlatformDefaults.getModCount();
- if (lastModCount != mc) {
- grid = null;
- lastModCount = mc;
- }
-
- if (parent.isValid() == false) {
-
- int hash = 0;
- for (Iterator<ComponentWrapper> it = ccMap.keySet().iterator(); it.hasNext();)
- hash += it.next().getLayoutHashCode();
-
- if (hash != lastHash) {
- grid = null;
- lastHash = hash;
- }
-
- Dimension ps = parent.getSize();
- if (lastInvalidSize == null || !lastInvalidSize.equals(ps)) {
- if (grid != null)
- grid.invalidateContainerSize();
- lastInvalidSize = ps;
- }
- }
-
- ContainerWrapper par = checkParent(parent);
-
- setDebug(par, lc.getDebugMillis() > 0);
-
- if (grid == null)
- grid = new Grid(par, lc, rowSpecs, colSpecs, ccMap, callbackList);
- }
-
- private final ContainerWrapper checkParent(Container parent)
- {
- if (parent == null)
- return null;
-
- if (cacheParentW == null || cacheParentW.getComponent() != parent)
- cacheParentW = new SwingContainerWrapper(parent);
-
- return cacheParentW;
- }
-
- public void layoutContainer(Container parent)
- {
- synchronized(parent.getTreeLock()) {
- checkCache(parent);
-
- Insets i = parent.getInsets();
- int[] b = new int[] {
- i.left,
- i.top,
- parent.getWidth() - i.left - i.right,
- parent.getHeight() - i.top - i.bottom
- };
-
- grid.layout(b, lc.getAlignX(), lc.getAlignY(), getDebug(), false);
- lastInvalidSize = null;
- }
- }
-
- public Dimension minimumLayoutSize(Container parent)
- {
- synchronized(parent.getTreeLock()) {
- return getSizeImpl(parent, LayoutUtil.MIN);
- }
- }
-
- public Dimension preferredLayoutSize(Container parent)
- {
- synchronized(parent.getTreeLock()) {
- return getSizeImpl(parent, LayoutUtil.PREF);
- }
- }
-
- public Dimension maximumLayoutSize(Container parent)
- {
- return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
- }
-
- // Implementation method that does the job.
- private Dimension getSizeImpl(Container parent, int sizeType)
- {
- checkCache(parent);
-
- Insets i = parent.getInsets();
-
- int w = LayoutUtil.getSizeSafe(grid != null ? grid.getWidth() : null, sizeType) + i.left + i.right;
- int h = LayoutUtil.getSizeSafe(grid != null ? grid.getHeight() : null, sizeType) + i.top + i.bottom;
-
- return new Dimension(w, h);
- }
-
- public float getLayoutAlignmentX(Container parent)
- {
- return lc != null && lc.getAlignX() != null ? lc.getAlignX().getPixels(1, checkParent(parent), null) : 0;
- }
-
- public float getLayoutAlignmentY(Container parent)
- {
- return lc != null && lc.getAlignY() != null ? lc.getAlignY().getPixels(1, checkParent(parent), null) : 0;
- }
-
- public void addLayoutComponent(String s, Component comp)
- {
- addLayoutComponent(comp, s);
- }
-
- public void addLayoutComponent(Component comp, Object constraints)
- {
- synchronized(comp.getParent().getTreeLock()) {
- setComponentConstraintsImpl(comp, constraints, true);
- }
- }
-
- public void removeLayoutComponent(Component comp)
- {
- synchronized(comp.getParent().getTreeLock()) {
- scrConstrMap.remove(comp);
- ccMap.remove(new SwingComponentWrapper(comp));
- }
- }
-
- public void invalidateLayout(Container target)
- {
- if (lc.isNoCache())
- grid = null;
-
- // the validity of components is maintained automatically.
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
-
- public void writeExternal(ObjectOutput out) throws IOException
- {
- if (getClass() == MigLayout.class)
- LayoutUtil.writeAsXML(out, this);
- }
+package net.miginfocom.swing; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +import net.miginfocom.layout.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.*; +import java.util.*; + +/** A very flexbile layout manager. + * <p> + * Read the documentation that came with this layout manager for information on usage. + */ +public final class MigLayout implements LayoutManager2, Externalizable +{ + // ******** Instance part ******** + + /** The component to string constraints mappings. + */ + private final Map<Component, Object> scrConstrMap = new IdentityHashMap<Component, Object>(8); + + /** Hold the serializable text representation of the constraints. + */ + private Object layoutConstraints = "", colConstraints = "", rowConstraints = ""; // Should never be null! + + + // ******** Transient part ******** + + private transient ContainerWrapper cacheParentW = null; + + private transient final Map<ComponentWrapper, CC> ccMap = new HashMap<ComponentWrapper, CC>(8); + private transient javax.swing.Timer debugTimer = null; + + private transient LC lc = null; + private transient AC colSpecs = null, rowSpecs = null; + private transient Grid grid = null; + private transient int lastModCount = PlatformDefaults.getModCount(); + private transient int lastHash = -1; + private transient Dimension lastInvalidSize = null; + + private transient ArrayList<LayoutCallback> callbackList = null; + + /** Constructor with no constraints. + */ + public MigLayout() + { + this("", "", ""); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "". + */ + public MigLayout(String layoutConstraints) + { + this(layoutConstraints, "", ""); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "". + * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as "". + */ + public MigLayout(String layoutConstraints, String colConstraints) + { + this(layoutConstraints, colConstraints, ""); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "". + * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as "". + * @param rowConstraints The constraints for the rows in the grid. <code>null</code> will be treated as "". + */ + public MigLayout(String layoutConstraints, String colConstraints, String rowConstraints) + { + setLayoutConstraints(layoutConstraints); + setColumnConstraints(colConstraints); + setRowConstraints(rowConstraints); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint. + */ + public MigLayout(LC layoutConstraints) + { + this(layoutConstraints, null, null); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint. + * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as an empty constraint. + */ + public MigLayout(LC layoutConstraints, AC colConstraints) + { + this(layoutConstraints, colConstraints, null); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint. + * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as an empty constraint. + * @param rowConstraints The constraints for the rows in the grid. <code>null</code> will be treated as an empty constraint. + */ + public MigLayout(LC layoutConstraints, AC colConstraints, AC rowConstraints) + { + setLayoutConstraints(layoutConstraints); + setColumnConstraints(colConstraints); + setRowConstraints(rowConstraints); + } + + /** Returns layout constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in + * to the constructor or set with {@link #setLayoutConstraints(Object)}. + * @return The layout constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in + * to the constructor or set with {@link #setLayoutConstraints(Object)}. Never <code>null</code>. + */ + public Object getLayoutConstraints() + { + return layoutConstraints; + } + + /** Sets the layout constraints for the layout manager instance as a String. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage. + * @throws RuntimeException if the constaint was not valid. + */ + public void setLayoutConstraints(Object constr) + { + if (constr == null || constr instanceof String) { + constr = ConstraintParser.prepare((String) constr); + lc = ConstraintParser.parseLayoutConstraint((String) constr); + } else if (constr instanceof LC) { + lc = (LC) constr; + } else { + throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString()); + } + layoutConstraints = constr; + grid = null; + } + + /** Returns the column layout constraints either as a <code>String</code> or {@link net.miginfocom.layout.AC}. + * @return The column constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in + * to the constructor or set with {@link #setLayoutConstraints(Object)}. Never <code>null</code>. + */ + public Object getColumnConstraints() + { + return colConstraints; + } + + /** Sets the column layout constraints for the layout manager instance as a String. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The column layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage. + * @throws RuntimeException if the constaint was not valid. + */ + public void setColumnConstraints(Object constr) + { + if (constr == null || constr instanceof String) { + constr = ConstraintParser.prepare((String) constr); + colSpecs = ConstraintParser.parseColumnConstraints((String) constr); + } else if (constr instanceof AC) { + colSpecs = (AC) constr; + } else { + throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString()); + } + colConstraints = constr; + grid = null; + } + + /** Returns the row layout constraints as a String representation. This string is the exact string as set with {@link #setRowConstraints(Object)} + * or sent into the constructor. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @return The row layout constraints as a String representation. Never <code>null</code>. + */ + public Object getRowConstraints() + { + return rowConstraints; + } + + /** Sets the row layout constraints for the layout manager instance as a String. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The row layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage. + * @throws RuntimeException if the constaint was not valid. + */ + public void setRowConstraints(Object constr) + { + if (constr == null || constr instanceof String) { + constr = ConstraintParser.prepare((String) constr); + rowSpecs = ConstraintParser.parseRowConstraints((String) constr); + } else if (constr instanceof AC) { + rowSpecs = (AC) constr; + } else { + throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString()); + } + rowConstraints = constr; + grid = null; + } + + /** Returns the component constraints as a String representation. This string is the exact string as set with {@link #setComponentConstraints(java.awt.Component, Object)} + * or set when adding the component to the parent component. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param comp The component to return the constraints for. + * @return The component constraints as a String representation ir <code>null</code> if the component is not registered + * with this layout manager. The returned values is either a String or a {@link net.miginfocom.layout.CC} + * depending on what constraint was sent in when the component was added. May be <code>null</code>. + */ + public Object getComponentConstraints(Component comp) + { + synchronized(comp.getParent().getTreeLock()) { + return scrConstrMap.get(comp); + } + } + + /** Sets the component constraint for the component that already must be handleded by this layout manager. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The component constraints as a String or {@link net.miginfocom.layout.CC}. <code>null</code> is ok. + * @param comp The component to set the constraints for. + * @throws RuntimeException if the constaint was not valid. + * @throws IllegalArgumentException If the component is not handlering the component. + */ + public void setComponentConstraints(Component comp, Object constr) + { + setComponentConstraintsImpl(comp, constr, false); + } + + /** Sets the component constraint for the component that already must be handleded by this layout manager. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The component constraints as a String or {@link net.miginfocom.layout.CC}. <code>null</code> is ok. + * @param comp The component to set the constraints for. + * @throws RuntimeException if the constaint was not valid. + * @throws IllegalArgumentException If the component is not handling the component. + */ + private void setComponentConstraintsImpl(Component comp, Object constr, boolean noCheck) + { + Container parent = comp.getParent(); + synchronized(parent.getTreeLock()) { + if (noCheck == false && scrConstrMap.containsKey(comp) == false) + throw new IllegalArgumentException("Component must already be added to parent!"); + + ComponentWrapper cw = new SwingComponentWrapper(comp); + + if (constr == null || constr instanceof String) { + String cStr = ConstraintParser.prepare((String) constr); + + scrConstrMap.put(comp, constr); + ccMap.put(cw, ConstraintParser.parseComponentConstraint(cStr)); + + } else if (constr instanceof CC) { + + scrConstrMap.put(comp, constr); + ccMap.put(cw, (CC) constr); + + } else { + throw new IllegalArgumentException("Constraint must be String or ComponentConstraint: " + constr.getClass().toString()); + } + + grid = null; + } + } + + /** Returns if this layout manager is currently managing this component. + * @param c The component to check. If <code>null</code> then <code>false</code> will be returned. + * @return If this layout manager is currently managing this component. + */ + public boolean isManagingComponent(Component c) + { + return scrConstrMap.containsKey(c); + } + + /** Adds the callback function that will be called at different stages of the layout cylce. + * @param callback The callback. Not <code>null</code>. + */ + public void addLayoutCallback(LayoutCallback callback) + { + if (callback == null) + throw new NullPointerException(); + + if (callbackList == null) + callbackList = new ArrayList<LayoutCallback>(1); + + callbackList.add(callback); + } + + /** Removes the callback if it exists. + * @param callback The callback. May be <code>null</code>. + */ + public void removeLayoutCallback(LayoutCallback callback) + { + if (callbackList != null) + callbackList.remove(callback); + } + + /** Sets the debugging state for this layout manager instance. If debug is turned on a timer will repaint the last laid out parent + * with debug information on top. + * <p> + * Red fill and dashed darked red outline is used to indicate occupied cells in the grid. Blue dashed outline indicate indicate + * component bounds set. + * <p> + * Note that debug can also be set on the layout constraints. There it will be persisted. The calue set here will not. See the class + * JavaDocs for information. + * @param b <code>true</code> means debug is turned on. + */ + private synchronized void setDebug(final ComponentWrapper parentW, boolean b) + { + if (b && (debugTimer == null || debugTimer.getDelay() != lc.getDebugMillis())) { + if (debugTimer != null) + debugTimer.stop(); + + ContainerWrapper pCW = parentW.getParent(); + final Component parent = pCW != null ? (Component) pCW.getComponent() : null; + + debugTimer = new javax.swing.Timer(lc.getDebugMillis(), new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (grid != null) + grid.paintDebug(); + } + }); + + if (parent != null) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Container p = parent.getParent(); + if (p != null) { + if (p instanceof JComponent) { + ((JComponent) p).revalidate(); + } else { + parent.invalidate(); + p.validate(); + } + } + } + }); + } + + debugTimer.setInitialDelay(100); + debugTimer.start(); + + } else if (!b && debugTimer != null) { + debugTimer.stop(); + debugTimer = null; + } + } + + /** Returns the current debugging state. + * @return The current debugging state. + */ + private boolean getDebug() + { + return debugTimer != null; + } + + /** Check if something has changed and if so recrete it to the cached objects. + * @param parent The parent that is the target for this layout manager. + */ + private final void checkCache(Container parent) + { + if (parent == null) + return; + + // Check if the grid is valid + int mc = PlatformDefaults.getModCount(); + if (lastModCount != mc) { + grid = null; + lastModCount = mc; + } + + if (parent.isValid() == false) { + + int hash = 0; + for (Iterator<ComponentWrapper> it = ccMap.keySet().iterator(); it.hasNext();) + hash += it.next().getLayoutHashCode(); + + if (hash != lastHash) { + grid = null; + lastHash = hash; + } + + Dimension ps = parent.getSize(); + if (lastInvalidSize == null || !lastInvalidSize.equals(ps)) { + if (grid != null) + grid.invalidateContainerSize(); + lastInvalidSize = ps; + } + } + + ContainerWrapper par = checkParent(parent); + + setDebug(par, lc.getDebugMillis() > 0); + + if (grid == null) + grid = new Grid(par, lc, rowSpecs, colSpecs, ccMap, callbackList); + } + + private final ContainerWrapper checkParent(Container parent) + { + if (parent == null) + return null; + + if (cacheParentW == null || cacheParentW.getComponent() != parent) + cacheParentW = new SwingContainerWrapper(parent); + + return cacheParentW; + } + + public void layoutContainer(Container parent) + { + synchronized(parent.getTreeLock()) { + checkCache(parent); + + Insets i = parent.getInsets(); + int[] b = new int[] { + i.left, + i.top, + parent.getWidth() - i.left - i.right, + parent.getHeight() - i.top - i.bottom + }; + + grid.layout(b, lc.getAlignX(), lc.getAlignY(), getDebug(), false); + lastInvalidSize = null; + } + } + + public Dimension minimumLayoutSize(Container parent) + { + synchronized(parent.getTreeLock()) { + return getSizeImpl(parent, LayoutUtil.MIN); + } + } + + public Dimension preferredLayoutSize(Container parent) + { + synchronized(parent.getTreeLock()) { + return getSizeImpl(parent, LayoutUtil.PREF); + } + } + + public Dimension maximumLayoutSize(Container parent) + { + return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); + } + + // Implementation method that does the job. + private Dimension getSizeImpl(Container parent, int sizeType) + { + checkCache(parent); + + Insets i = parent.getInsets(); + + int w = LayoutUtil.getSizeSafe(grid != null ? grid.getWidth() : null, sizeType) + i.left + i.right; + int h = LayoutUtil.getSizeSafe(grid != null ? grid.getHeight() : null, sizeType) + i.top + i.bottom; + + return new Dimension(w, h); + } + + public float getLayoutAlignmentX(Container parent) + { + return lc != null && lc.getAlignX() != null ? lc.getAlignX().getPixels(1, checkParent(parent), null) : 0; + } + + public float getLayoutAlignmentY(Container parent) + { + return lc != null && lc.getAlignY() != null ? lc.getAlignY().getPixels(1, checkParent(parent), null) : 0; + } + + public void addLayoutComponent(String s, Component comp) + { + addLayoutComponent(comp, s); + } + + public void addLayoutComponent(Component comp, Object constraints) + { + synchronized(comp.getParent().getTreeLock()) { + setComponentConstraintsImpl(comp, constraints, true); + } + } + + public void removeLayoutComponent(Component comp) + { + synchronized(comp.getParent().getTreeLock()) { + scrConstrMap.remove(comp); + ccMap.remove(new SwingComponentWrapper(comp)); + } + } + + public void invalidateLayout(Container target) + { + if (lc.isNoCache()) + grid = null; + + // the validity of components is maintained automatically. + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + if (getClass() == MigLayout.class) + LayoutUtil.writeAsXML(out, this); + } }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/swing/SwingComponentWrapper.java b/prototypes/miglayout/net/miginfocom/swing/SwingComponentWrapper.java index 35b069be..0c496c0b 100644 --- a/prototypes/miglayout/net/miginfocom/swing/SwingComponentWrapper.java +++ b/prototypes/miglayout/net/miginfocom/swing/SwingComponentWrapper.java @@ -1,426 +1,426 @@ -package net.miginfocom.swing;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-import net.miginfocom.layout.ComponentWrapper;
-import net.miginfocom.layout.ContainerWrapper;
-import net.miginfocom.layout.PlatformDefaults;
-
-import javax.swing.*;
-import javax.swing.text.JTextComponent;
-import java.awt.*;
-import java.awt.geom.Rectangle2D;
-import java.lang.reflect.Method;
-import java.util.IdentityHashMap;
-
-/**
- */
-public class SwingComponentWrapper implements ComponentWrapper
-{
- private static boolean maxSet = false;
-
- private static boolean vp = true;
-
- /** Debug color for component bounds outline.
- */
- private static final Color DB_COMP_OUTLINE = new Color(0, 0, 200);
-
- private final Component c;
- private int compType = TYPE_UNSET;
- private final boolean bl;
-
- public SwingComponentWrapper(Component c)
- {
- this.c = c;
- bl = getBaseline(c.getWidth(), c.getHeight()) != -1;
- }
-
- public final int getBaseline(int width, int height)
- {
- if (BL_METHOD == null)
- return -1;
-
- try {
- Object[] args = new Object[] {
- new Integer(width == -1 ? c.getWidth() : width),
- new Integer(height == -1 ? c.getHeight() : height)
- };
- return ((Integer) BL_METHOD.invoke(c, args)).intValue();
- } catch (Exception e) {
- return -1;
- }
- }
-
- public final Object getComponent()
- {
- return c;
- }
-
- /** Cache.
- */
- private final static IdentityHashMap<FontMetrics, Point.Float> FM_MAP = new IdentityHashMap<FontMetrics, Point.Float>(4);
- private final static Font SUBST_FONT = new Font("sansserif", Font.PLAIN, 11);
-
- public final float getPixelUnitFactor(boolean isHor)
- {
- switch (PlatformDefaults.getLogicalPixelBase()) {
- case PlatformDefaults.BASE_FONT_SIZE:
- Font font = c.getFont();
- FontMetrics fm = c.getFontMetrics(font != null ? font : SUBST_FONT);
- Point.Float p = FM_MAP.get(fm);
- if (p == null) {
- Rectangle2D r = fm.getStringBounds("X", c.getGraphics());
- p = new Point.Float(((float) r.getWidth()) / 6f, ((float) r.getHeight()) / 13.27734375f);
- FM_MAP.put(fm, p);
- }
- return isHor ? p.x : p.y;
-
- case PlatformDefaults.BASE_SCALE_FACTOR:
- Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor();
- if (s != null)
- return s.floatValue();
- return (isHor ? getHorizontalScreenDPI() : getVerticalScreenDPI()) / (float) PlatformDefaults.getDefaultDPI();
-
- default:
- return 1f;
- }
- }
-
-// /** Cache.
-// */
-// private final static IdentityHashMap<FontMetrics, Point.Float> FM_MAP2 = new IdentityHashMap<FontMetrics, Point.Float>(4);
-// private final static Font SUBST_FONT2 = new Font("sansserif", Font.PLAIN, 11);
-//
-// public float getDialogUnit(boolean isHor)
-// {
-// Font font = c.getFont();
-// FontMetrics fm = c.getFontMetrics(font != null ? font : SUBST_FONT2);
-// Point.Float dluP = FM_MAP2.get(fm);
-// if (dluP == null) {
-// float w = fm.charWidth('X') / 4f;
-// int ascent = fm.getAscent();
-// float h = (ascent > 14 ? ascent : ascent + (15 - ascent) / 3) / 8f;
-//
-// dluP = new Point.Float(w, h);
-// FM_MAP2.put(fm, dluP);
-// }
-// return isHor ? dluP.x : dluP.y;
-// }
-
- public final int getX()
- {
- return c.getX();
- }
-
- public final int getY()
- {
- return c.getY();
- }
-
- public final int getHeight()
- {
- return c.getHeight();
- }
-
- public final int getWidth()
- {
- return c.getWidth();
- }
-
- public final int getScreenLocationX()
- {
- Point p = new Point();
- SwingUtilities.convertPointToScreen(p, c);
- return p.x;
- }
-
- public final int getScreenLocationY()
- {
- Point p = new Point();
- SwingUtilities.convertPointToScreen(p, c);
- return p.y;
- }
-
- public final int getMinimumHeight()
- {
- c.getPreferredSize(); // To defeat a bug where the minimum size is difference before and after the first call to getPreferredSize();
- return c.getMinimumSize().height;
- }
-
- public final int getMinimumWidth()
- {
- c.getPreferredSize(); // To defeat a bug where the minimum size is difference before and after the first call to getPreferredSize();
- return c.getMinimumSize().width;
- }
-
- public final int getPreferredHeight()
- {
- return c.getPreferredSize().height;
- }
-
- public final int getPreferredWidth()
- {
- return c.getPreferredSize().width;
- }
-
- public final int getMaximumHeight()
- {
- if (!isMaxSet(c))
- return Short.MAX_VALUE;
-
- return c.getMaximumSize().height;
- }
-
- public final int getMaximumWidth()
- {
- if (!isMaxSet(c))
- return Short.MAX_VALUE;
-
- return c.getMaximumSize().width;
- }
-
-
- private boolean isMaxSet(Component c)
- {
- if (IMS_METHOD != null) {
- try {
- return ((Boolean) IMS_METHOD.invoke(c, null)).booleanValue();
- } catch (Exception e) {
- IMS_METHOD = null; // So we do not try every time.
- }
- }
- return isMaxSizeSetOn1_4();
- }
-
- public final ContainerWrapper getParent()
- {
- Container p = c.getParent();
- return p != null ? new SwingContainerWrapper(p) : null;
- }
-
- public final int getHorizontalScreenDPI()
- {
- return c.getToolkit().getScreenResolution();
- }
-
- public final int getVerticalScreenDPI()
- {
- return c.getToolkit().getScreenResolution();
- }
-
- public final int getScreenWidth()
- {
- return c.getToolkit().getScreenSize().width;
- }
-
- public final int getScreenHeight()
- {
- return c.getToolkit().getScreenSize().height;
- }
-
- public final boolean hasBaseline()
- {
- return bl;
- }
-
- public final String getLinkId()
- {
- return c.getName();
- }
-
- public final void setBounds(int x, int y, int width, int height)
- {
- c.setBounds(x, y, width, height);
- }
-
- public boolean isVisible()
- {
- return c.isVisible();
- }
-
- public final int[] getVisualPadding()
- {
- if (vp && c instanceof JTabbedPane) {
- if (UIManager.getLookAndFeel().getClass().getName().endsWith("WindowsLookAndFeel"))
- return new int[] {-1, 0, 2, 2};
- }
- return null;
- }
-
- public static boolean isMaxSizeSetOn1_4()
- {
- return maxSet;
- }
-
- public static void setMaxSizeSetOn1_4(boolean b)
- {
- maxSet = b;
- }
-
- public final static boolean isVisualPaddingEnabled()
- {
- return vp;
- }
-
- public final static void setVisualPaddingEnabled(boolean b)
- {
- vp = b;
- }
-
- public final void paintDebugOutline()
- {
- if (c.isShowing() == false)
- return;
-
- Graphics2D g = (Graphics2D) c.getGraphics();
- if (g == null)
- return;
-
- g.setPaint(DB_COMP_OUTLINE);
- g.setStroke(new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[] {2f, 4f}, 0));
- g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
- }
-
- public int getComponetType(boolean disregardScrollPane)
- {
- if (compType == TYPE_UNSET)
- compType = checkType(disregardScrollPane);
-
- return compType;
- }
-
- public int getLayoutHashCode()
- {
- Dimension d = c.getMaximumSize();
- int h = d.width + (d.height << 5);
-
- d = c.getPreferredSize();
- h += (d.width << 10) + (d.height << 15);
-
- d = c.getMinimumSize();
- h += (d.width << 20) + (d.height << 25);
-
- if (c.isVisible())
- h += 1324511;
-
- String id = getLinkId();
- if (id != null)
- h += id.hashCode();
- return h;
-
- // Since 2.3 will check the isValid instead everything that affects that can be removed from the layout hashcode.
-
-// String id = getLinkId();
-// return id != null ? id.hashCode() : 1;
- }
-
- private final int checkType(boolean disregardScrollPane)
- {
- Component c = this.c;
-
- if (disregardScrollPane) {
- if (c instanceof JScrollPane) {
- c = ((JScrollPane) c).getViewport().getView();
- } else if (c instanceof ScrollPane) {
- c = ((ScrollPane) c).getComponent(0);
- }
- }
-
- if (c instanceof JTextField || c instanceof TextField) {
- return TYPE_TEXT_FIELD;
- } else if (c instanceof JLabel || c instanceof Label) {
- return TYPE_LABEL;
- } else if (c instanceof JToggleButton || c instanceof Checkbox) {
- return TYPE_CHECK_BOX;
- } else if (c instanceof AbstractButton || c instanceof Button) {
- return TYPE_BUTTON;
- } else if (c instanceof JComboBox || c instanceof Choice) {
- return TYPE_LABEL;
- } else if (c instanceof JTextComponent || c instanceof TextComponent) {
- return TYPE_TEXT_AREA;
- } else if (c instanceof JPanel || c instanceof Canvas) {
- return TYPE_PANEL;
- } else if (c instanceof JList || c instanceof List) {
- return TYPE_LIST;
- } else if (c instanceof JTable) {
- return TYPE_TABLE;
- } else if (c instanceof JSeparator) {
- return TYPE_SEPARATOR;
- } else if (c instanceof JSpinner) {
- return TYPE_SPINNER;
- } else if (c instanceof JProgressBar) {
- return TYPE_PROGRESS_BAR;
- } else if (c instanceof JSlider) {
- return TYPE_SLIDER;
- } else if (c instanceof JScrollPane) {
- return TYPE_SCROLL_PANE;
- } else if (c instanceof JScrollBar || c instanceof Scrollbar) {
- return TYPE_SCROLL_BAR;
- } else if (c instanceof Container) { // only AWT components is not containers.
- return TYPE_CONTAINER;
- }
- return TYPE_UNKNOWN;
- }
-
- public final int hashCode()
- {
- return getComponent().hashCode();
- }
-
- public final boolean equals(Object o)
- {
- if (o instanceof ComponentWrapper == false)
- return false;
-
- return getComponent().equals(((ComponentWrapper) o).getComponent());
- }
-
- /** Cached method used for getting base line with reflection.
- */
- private static Method BL_METHOD = null;
- static {
- try {
- BL_METHOD = Component.class.getDeclaredMethod("getBaseline", new Class[] {int.class, int.class});
- } catch (Throwable e) { // No such method or security exception
- }
- }
-
- private static Method IMS_METHOD = null;
- static {
- try {
- IMS_METHOD = Component.class.getDeclaredMethod("isMaximumSizeSet", null);
- } catch (Throwable e) { // No such method or security exception
- }
- }
-}
+package net.miginfocom.swing; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +import net.miginfocom.layout.ComponentWrapper; +import net.miginfocom.layout.ContainerWrapper; +import net.miginfocom.layout.PlatformDefaults; + +import javax.swing.*; +import javax.swing.text.JTextComponent; +import java.awt.*; +import java.awt.geom.Rectangle2D; +import java.lang.reflect.Method; +import java.util.IdentityHashMap; + +/** + */ +public class SwingComponentWrapper implements ComponentWrapper +{ + private static boolean maxSet = false; + + private static boolean vp = true; + + /** Debug color for component bounds outline. + */ + private static final Color DB_COMP_OUTLINE = new Color(0, 0, 200); + + private final Component c; + private int compType = TYPE_UNSET; + private final boolean bl; + + public SwingComponentWrapper(Component c) + { + this.c = c; + bl = getBaseline(c.getWidth(), c.getHeight()) != -1; + } + + public final int getBaseline(int width, int height) + { + if (BL_METHOD == null) + return -1; + + try { + Object[] args = new Object[] { + new Integer(width == -1 ? c.getWidth() : width), + new Integer(height == -1 ? c.getHeight() : height) + }; + return ((Integer) BL_METHOD.invoke(c, args)).intValue(); + } catch (Exception e) { + return -1; + } + } + + public final Object getComponent() + { + return c; + } + + /** Cache. + */ + private final static IdentityHashMap<FontMetrics, Point.Float> FM_MAP = new IdentityHashMap<FontMetrics, Point.Float>(4); + private final static Font SUBST_FONT = new Font("sansserif", Font.PLAIN, 11); + + public final float getPixelUnitFactor(boolean isHor) + { + switch (PlatformDefaults.getLogicalPixelBase()) { + case PlatformDefaults.BASE_FONT_SIZE: + Font font = c.getFont(); + FontMetrics fm = c.getFontMetrics(font != null ? font : SUBST_FONT); + Point.Float p = FM_MAP.get(fm); + if (p == null) { + Rectangle2D r = fm.getStringBounds("X", c.getGraphics()); + p = new Point.Float(((float) r.getWidth()) / 6f, ((float) r.getHeight()) / 13.27734375f); + FM_MAP.put(fm, p); + } + return isHor ? p.x : p.y; + + case PlatformDefaults.BASE_SCALE_FACTOR: + Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor(); + if (s != null) + return s.floatValue(); + return (isHor ? getHorizontalScreenDPI() : getVerticalScreenDPI()) / (float) PlatformDefaults.getDefaultDPI(); + + default: + return 1f; + } + } + +// /** Cache. +// */ +// private final static IdentityHashMap<FontMetrics, Point.Float> FM_MAP2 = new IdentityHashMap<FontMetrics, Point.Float>(4); +// private final static Font SUBST_FONT2 = new Font("sansserif", Font.PLAIN, 11); +// +// public float getDialogUnit(boolean isHor) +// { +// Font font = c.getFont(); +// FontMetrics fm = c.getFontMetrics(font != null ? font : SUBST_FONT2); +// Point.Float dluP = FM_MAP2.get(fm); +// if (dluP == null) { +// float w = fm.charWidth('X') / 4f; +// int ascent = fm.getAscent(); +// float h = (ascent > 14 ? ascent : ascent + (15 - ascent) / 3) / 8f; +// +// dluP = new Point.Float(w, h); +// FM_MAP2.put(fm, dluP); +// } +// return isHor ? dluP.x : dluP.y; +// } + + public final int getX() + { + return c.getX(); + } + + public final int getY() + { + return c.getY(); + } + + public final int getHeight() + { + return c.getHeight(); + } + + public final int getWidth() + { + return c.getWidth(); + } + + public final int getScreenLocationX() + { + Point p = new Point(); + SwingUtilities.convertPointToScreen(p, c); + return p.x; + } + + public final int getScreenLocationY() + { + Point p = new Point(); + SwingUtilities.convertPointToScreen(p, c); + return p.y; + } + + public final int getMinimumHeight() + { + c.getPreferredSize(); // To defeat a bug where the minimum size is difference before and after the first call to getPreferredSize(); + return c.getMinimumSize().height; + } + + public final int getMinimumWidth() + { + c.getPreferredSize(); // To defeat a bug where the minimum size is difference before and after the first call to getPreferredSize(); + return c.getMinimumSize().width; + } + + public final int getPreferredHeight() + { + return c.getPreferredSize().height; + } + + public final int getPreferredWidth() + { + return c.getPreferredSize().width; + } + + public final int getMaximumHeight() + { + if (!isMaxSet(c)) + return Short.MAX_VALUE; + + return c.getMaximumSize().height; + } + + public final int getMaximumWidth() + { + if (!isMaxSet(c)) + return Short.MAX_VALUE; + + return c.getMaximumSize().width; + } + + + private boolean isMaxSet(Component c) + { + if (IMS_METHOD != null) { + try { + return ((Boolean) IMS_METHOD.invoke(c, null)).booleanValue(); + } catch (Exception e) { + IMS_METHOD = null; // So we do not try every time. + } + } + return isMaxSizeSetOn1_4(); + } + + public final ContainerWrapper getParent() + { + Container p = c.getParent(); + return p != null ? new SwingContainerWrapper(p) : null; + } + + public final int getHorizontalScreenDPI() + { + return c.getToolkit().getScreenResolution(); + } + + public final int getVerticalScreenDPI() + { + return c.getToolkit().getScreenResolution(); + } + + public final int getScreenWidth() + { + return c.getToolkit().getScreenSize().width; + } + + public final int getScreenHeight() + { + return c.getToolkit().getScreenSize().height; + } + + public final boolean hasBaseline() + { + return bl; + } + + public final String getLinkId() + { + return c.getName(); + } + + public final void setBounds(int x, int y, int width, int height) + { + c.setBounds(x, y, width, height); + } + + public boolean isVisible() + { + return c.isVisible(); + } + + public final int[] getVisualPadding() + { + if (vp && c instanceof JTabbedPane) { + if (UIManager.getLookAndFeel().getClass().getName().endsWith("WindowsLookAndFeel")) + return new int[] {-1, 0, 2, 2}; + } + return null; + } + + public static boolean isMaxSizeSetOn1_4() + { + return maxSet; + } + + public static void setMaxSizeSetOn1_4(boolean b) + { + maxSet = b; + } + + public final static boolean isVisualPaddingEnabled() + { + return vp; + } + + public final static void setVisualPaddingEnabled(boolean b) + { + vp = b; + } + + public final void paintDebugOutline() + { + if (c.isShowing() == false) + return; + + Graphics2D g = (Graphics2D) c.getGraphics(); + if (g == null) + return; + + g.setPaint(DB_COMP_OUTLINE); + g.setStroke(new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[] {2f, 4f}, 0)); + g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); + } + + public int getComponetType(boolean disregardScrollPane) + { + if (compType == TYPE_UNSET) + compType = checkType(disregardScrollPane); + + return compType; + } + + public int getLayoutHashCode() + { + Dimension d = c.getMaximumSize(); + int h = d.width + (d.height << 5); + + d = c.getPreferredSize(); + h += (d.width << 10) + (d.height << 15); + + d = c.getMinimumSize(); + h += (d.width << 20) + (d.height << 25); + + if (c.isVisible()) + h += 1324511; + + String id = getLinkId(); + if (id != null) + h += id.hashCode(); + return h; + + // Since 2.3 will check the isValid instead everything that affects that can be removed from the layout hashcode. + +// String id = getLinkId(); +// return id != null ? id.hashCode() : 1; + } + + private final int checkType(boolean disregardScrollPane) + { + Component c = this.c; + + if (disregardScrollPane) { + if (c instanceof JScrollPane) { + c = ((JScrollPane) c).getViewport().getView(); + } else if (c instanceof ScrollPane) { + c = ((ScrollPane) c).getComponent(0); + } + } + + if (c instanceof JTextField || c instanceof TextField) { + return TYPE_TEXT_FIELD; + } else if (c instanceof JLabel || c instanceof Label) { + return TYPE_LABEL; + } else if (c instanceof JToggleButton || c instanceof Checkbox) { + return TYPE_CHECK_BOX; + } else if (c instanceof AbstractButton || c instanceof Button) { + return TYPE_BUTTON; + } else if (c instanceof JComboBox || c instanceof Choice) { + return TYPE_LABEL; + } else if (c instanceof JTextComponent || c instanceof TextComponent) { + return TYPE_TEXT_AREA; + } else if (c instanceof JPanel || c instanceof Canvas) { + return TYPE_PANEL; + } else if (c instanceof JList || c instanceof List) { + return TYPE_LIST; + } else if (c instanceof JTable) { + return TYPE_TABLE; + } else if (c instanceof JSeparator) { + return TYPE_SEPARATOR; + } else if (c instanceof JSpinner) { + return TYPE_SPINNER; + } else if (c instanceof JProgressBar) { + return TYPE_PROGRESS_BAR; + } else if (c instanceof JSlider) { + return TYPE_SLIDER; + } else if (c instanceof JScrollPane) { + return TYPE_SCROLL_PANE; + } else if (c instanceof JScrollBar || c instanceof Scrollbar) { + return TYPE_SCROLL_BAR; + } else if (c instanceof Container) { // only AWT components is not containers. + return TYPE_CONTAINER; + } + return TYPE_UNKNOWN; + } + + public final int hashCode() + { + return getComponent().hashCode(); + } + + public final boolean equals(Object o) + { + if (o instanceof ComponentWrapper == false) + return false; + + return getComponent().equals(((ComponentWrapper) o).getComponent()); + } + + /** Cached method used for getting base line with reflection. + */ + private static Method BL_METHOD = null; + static { + try { + BL_METHOD = Component.class.getDeclaredMethod("getBaseline", new Class[] {int.class, int.class}); + } catch (Throwable e) { // No such method or security exception + } + } + + private static Method IMS_METHOD = null; + static { + try { + IMS_METHOD = Component.class.getDeclaredMethod("isMaximumSizeSet", null); + } catch (Throwable e) { // No such method or security exception + } + } +} diff --git a/prototypes/miglayout/net/miginfocom/swing/SwingContainerWrapper.java b/prototypes/miglayout/net/miginfocom/swing/SwingContainerWrapper.java index ae48876e..acb9c95a 100644 --- a/prototypes/miglayout/net/miginfocom/swing/SwingContainerWrapper.java +++ b/prototypes/miglayout/net/miginfocom/swing/SwingContainerWrapper.java @@ -1,108 +1,108 @@ -package net.miginfocom.swing;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-import net.miginfocom.layout.ComponentWrapper;
-import net.miginfocom.layout.ContainerWrapper;
-
-import java.awt.*;
-
-/**
- */
-public final class SwingContainerWrapper extends SwingComponentWrapper implements ContainerWrapper
-{
- /** Debug color for cell outline.
- */
- private static final Color DB_CELL_OUTLINE = new Color(255, 0, 0);
-
- public SwingContainerWrapper(Container c)
- {
- super(c);
- }
-
- public ComponentWrapper[] getComponents()
- {
- Container c = (Container) getComponent();
- ComponentWrapper[] cws = new ComponentWrapper[c.getComponentCount()];
- for (int i = 0; i < cws.length; i++)
- cws[i] = new SwingComponentWrapper(c.getComponent(i));
- return cws;
- }
-
- public int getComponentCount()
- {
- return ((Container) getComponent()).getComponentCount();
- }
-
- public Object getLayout()
- {
- return ((Container) getComponent()).getLayout();
- }
-
- public final boolean isLeftToRight()
- {
- return ((Container) getComponent()).getComponentOrientation().isLeftToRight();
- }
-
- public final void paintDebugCell(int x, int y, int width, int height)
- {
- Component c = (Component) getComponent();
- if (c.isShowing() == false)
- return;
-
- Graphics2D g = (Graphics2D) c.getGraphics();
- if (g == null)
- return;
-
- g.setStroke(new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[] {2f, 3f}, 0));
- g.setPaint(DB_CELL_OUTLINE);
- g.drawRect(x, y, width - 1, height - 1);
- }
-
- public int getComponetType(boolean disregardScrollPane)
- {
- return TYPE_CONTAINER;
- }
-
- // Removed for 2.3 because the parent.isValid() in MigLayout will catch this instead.
-// public int getLayoutHashCode()
-// {
-// int h = super.getLayoutHashCode();
-//
-// if (isLeftToRight())
-// h += 416343;
-//
-// return h;
-// }
-}
+package net.miginfocom.swing; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +import net.miginfocom.layout.ComponentWrapper; +import net.miginfocom.layout.ContainerWrapper; + +import java.awt.*; + +/** + */ +public final class SwingContainerWrapper extends SwingComponentWrapper implements ContainerWrapper +{ + /** Debug color for cell outline. + */ + private static final Color DB_CELL_OUTLINE = new Color(255, 0, 0); + + public SwingContainerWrapper(Container c) + { + super(c); + } + + public ComponentWrapper[] getComponents() + { + Container c = (Container) getComponent(); + ComponentWrapper[] cws = new ComponentWrapper[c.getComponentCount()]; + for (int i = 0; i < cws.length; i++) + cws[i] = new SwingComponentWrapper(c.getComponent(i)); + return cws; + } + + public int getComponentCount() + { + return ((Container) getComponent()).getComponentCount(); + } + + public Object getLayout() + { + return ((Container) getComponent()).getLayout(); + } + + public final boolean isLeftToRight() + { + return ((Container) getComponent()).getComponentOrientation().isLeftToRight(); + } + + public final void paintDebugCell(int x, int y, int width, int height) + { + Component c = (Component) getComponent(); + if (c.isShowing() == false) + return; + + Graphics2D g = (Graphics2D) c.getGraphics(); + if (g == null) + return; + + g.setStroke(new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[] {2f, 3f}, 0)); + g.setPaint(DB_CELL_OUTLINE); + g.drawRect(x, y, width - 1, height - 1); + } + + public int getComponetType(boolean disregardScrollPane) + { + return TYPE_CONTAINER; + } + + // Removed for 2.3 because the parent.isValid() in MigLayout will catch this instead. +// public int getLayoutHashCode() +// { +// int h = super.getLayoutHashCode(); +// +// if (isLeftToRight()) +// h += 416343; +// +// return h; +// } +} diff --git a/prototypes/miglayout/net/miginfocom/swt/MigLayout.java b/prototypes/miglayout/net/miginfocom/swt/MigLayout.java index a36408fb..7cb9a6fa 100644 --- a/prototypes/miglayout/net/miginfocom/swt/MigLayout.java +++ b/prototypes/miglayout/net/miginfocom/swt/MigLayout.java @@ -1,506 +1,506 @@ -package net.miginfocom.swt;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-import net.miginfocom.layout.*;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.swt.widgets.Composite;
-
-import java.io.*;
-import java.util.*;
-
-/** A very flexbile layout manager.
- * <p>
- * Read the documentation that came with this layout manager for information on usage.
- */
-public final class MigLayout extends Layout implements Externalizable
-{
- // ******** Instance part ********
-
- /** The component to string constraints mappings.
- */
- private final Map<Control, Object> scrConstrMap = new IdentityHashMap<Control, Object>(8);
-
- /** Hold the serializable text representation of the constraints.
- */
- private Object layoutConstraints = "", colConstraints = "", rowConstraints = ""; // Should never be null!
-
- // ******** Transient part ********
-
- private transient ContainerWrapper cacheParentW = null;
-
- private transient final Map<ComponentWrapper, CC> ccMap = new HashMap<ComponentWrapper, CC>(8);
-
- private transient LC lc = null;
- private transient AC colSpecs = null, rowSpecs = null;
- private transient Grid grid = null;
-
- private transient java.util.Timer debugTimer = null;
- private transient long curDelay = -1;
- private transient int lastModCount = PlatformDefaults.getModCount();
- private transient int lastHash = -1;
-
- private transient ArrayList<LayoutCallback> callbackList = null;
-
- /** Constructor with no constraints.
- */
- public MigLayout()
- {
- this("", "", "");
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "".
- */
- public MigLayout(String layoutConstraints)
- {
- this(layoutConstraints, "", "");
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "".
- * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as "".
- */
- public MigLayout(String layoutConstraints, String colConstraints)
- {
- this(layoutConstraints, colConstraints, "");
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "".
- * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as "".
- * @param rowConstraints The constraints for the rows in the grid. <code>null</code> will be treated as "".
- */
- public MigLayout(String layoutConstraints, String colConstraints, String rowConstraints)
- {
- setLayoutConstraints(layoutConstraints);
- setColumnConstraints(colConstraints);
- setRowConstraints(rowConstraints);
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint.
- */
- public MigLayout(LC layoutConstraints)
- {
- this(layoutConstraints, null, null);
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint.
- * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as an empty constraint.
- */
- public MigLayout(LC layoutConstraints, AC colConstraints)
- {
- this(layoutConstraints, colConstraints, null);
- }
-
- /** Constructor.
- * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint.
- * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as an empty constraint.
- * @param rowConstraints The constraints for the rows in the grid. <code>null</code> will be treated as an empty constraint.
- */
- public MigLayout(LC layoutConstraints, AC colConstraints, AC rowConstraints)
- {
- setLayoutConstraints(layoutConstraints);
- setColumnConstraints(colConstraints);
- setRowConstraints(rowConstraints);
- }
-
- /** Returns layout constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in
- * to the constructor or set with {@link #setLayoutConstraints(Object)}.
- * @return The layout constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in
- * to the constructor or set with {@link #setLayoutConstraints(Object)}. Never <code>null</code>.
- */
- public Object getLayoutConstraints()
- {
- return layoutConstraints;
- }
-
- /** Sets the layout constraints for the layout manager instance as a String.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param s The layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage.
- * @throws RuntimeException if the constaint was not valid.
- */
- public void setLayoutConstraints(Object s)
- {
- if (s == null || s instanceof String) {
- s = ConstraintParser.prepare((String) s);
- lc = ConstraintParser.parseLayoutConstraint((String) s);
- } else if (s instanceof LC) {
- lc = (LC) s;
- } else {
- throw new IllegalArgumentException("Illegal constraint type: " + s.getClass().toString());
- }
- layoutConstraints = s;
- grid = null;
- }
-
- /** Returns the column layout constraints either as a <code>String</code> or {@link net.miginfocom.layout.AC}.
- * @return The column constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in
- * to the constructor or set with {@link #setLayoutConstraints(Object)}. Never <code>null</code>.
- */
- public Object getColumnConstraints()
- {
- return colConstraints;
- }
-
- /** Sets the column layout constraints for the layout manager instance as a String.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The column layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage.
- * @throws RuntimeException if the constaint was not valid.
- */
- public void setColumnConstraints(Object constr)
- {
- if (constr == null || constr instanceof String) {
- constr = ConstraintParser.prepare((String) constr);
- colSpecs = ConstraintParser.parseColumnConstraints((String) constr);
- } else if (constr instanceof AC) {
- colSpecs = (AC) constr;
- } else {
- throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString());
- }
- colConstraints = constr;
- grid = null;
- }
-
- /** Returns the row layout constraints as a String representation. This string is the exact string as set with {@link #setRowConstraints(Object)}
- * or sent into the constructor.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @return The row layout constraints as a String representation. Never <code>null</code>.
- */
- public Object getRowConstraints()
- {
- return rowConstraints;
- }
-
- /** Sets the row layout constraints for the layout manager instance as a String.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The row layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage.
- * @throws RuntimeException if the constaint was not valid.
- */
- public void setRowConstraints(Object constr)
- {
- if (constr == null || constr instanceof String) {
- constr = ConstraintParser.prepare((String) constr);
- rowSpecs = ConstraintParser.parseRowConstraints((String) constr);
- } else if (constr instanceof AC) {
- rowSpecs = (AC) constr;
- } else {
- throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString());
- }
- rowConstraints = constr;
- grid = null;
- }
-
- /** Returns the component constraints as a String representation. This string is the exact string as set with {@link #setComponentConstraints(org.eclipse.swt.widgets.Control, Object)}
- * or set when adding the component to the parent component.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param comp The component to return the constraints for.
- * @return The component constraints as a String representation ir <code>null</code> if the component is not registered
- * with this layout manager. The returned values is wither a String or a {@link net.miginfocom.layout.CC}
- * depending on what constraint was sent in when the component was added. May be <code>null</code>.
- */
- public Object getComponentConstraints(Control comp)
- {
- return scrConstrMap.get(comp);
- }
-
- /** Sets the component constraint for the component that already must be handleded by this layout manager.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The component constraints as a String or {@link net.miginfocom.layout.CC}. <code>null</code> is ok.
- * @param comp The component to set the constraints for.
- * @throws RuntimeException if the constaint was not valid.
- * @throws IllegalArgumentException If the component is not handlering the component.
- */
- public void setComponentConstraints(Control comp, Object constr)
- {
- setComponentConstraintsImpl(comp, constr, false);
- }
-
- /** Sets the component constraint for the component that already must be handleded by this layout manager.
- * <p>
- * See the class JavaDocs for information on how this string is formatted.
- * @param constr The component constraints as a String or {@link net.miginfocom.layout.CC}. <code>null</code> is ok.
- * @param comp The component to set the constraints for.
- * @throws RuntimeException if the constaint was not valid.
- * @throws IllegalArgumentException If the component is not handling the component.
- */
- private void setComponentConstraintsImpl(Control comp, Object constr, boolean noCheck)
- {
- if (noCheck == false && scrConstrMap.containsKey(comp) == false)
- throw new IllegalArgumentException("Component must already be added to parent!");
-
- ComponentWrapper cw = new SwtComponentWrapper(comp);
-
- if (constr == null || constr instanceof String) {
- String cStr = ConstraintParser.prepare((String) constr);
-
- scrConstrMap.put(comp, constr);
- ccMap.put(cw, ConstraintParser.parseComponentConstraint(cStr));
-
- } else if (constr instanceof CC) {
-
- scrConstrMap.put(comp, constr);
- ccMap.put(cw, (CC) constr);
-
- } else {
- throw new IllegalArgumentException("Constraint must be String or ComponentConstraint: " + constr.getClass().toString());
- }
- grid = null;
- }
-
- /** Returns if this layout manager is currently managing this component.
- * @param c The component to check. If <code>null</code> then <code>false</code> will be returned.
- * @return If this layout manager is currently managing this component.
- */
- public boolean isManagingComponent(Control c)
- {
- return scrConstrMap.containsKey(c);
- }
-
- /** Adds the callback function that will be called at different stages of the layout cylce.
- * @param callback The callback. Not <code>null</code>.
- */
- public void addLayoutCallback(LayoutCallback callback)
- {
- if (callback == null)
- throw new NullPointerException();
-
- if (callbackList == null)
- callbackList = new ArrayList<LayoutCallback>(1);
-
- callbackList.add(callback);
- }
-
- /** Removes the callback if it exists.
- * @param callback The callback. May be <code>null</code>.
- */
- public void removeLayoutCallback(LayoutCallback callback)
- {
- if (callbackList != null)
- callbackList.remove(callback);
- }
-
- /** Sets the debugging state for this layout manager instance. If debug is turned on a timer will repaint the last laid out parent
- * with debug information on top.
- * <p>
- * Red fill and dashed darked red outline is used to indicate occupied cells in the grid. Blue dashed outline indicate indicate
- * component bounds set.
- * <p>
- * Note that debug can also be set on the layout constraints. There it will be persisted. The calue set here will not. See the class
- * JavaDocs for information.
- * @param b <code>true</code> means debug is turned on.
- */
- private synchronized void setDebug(final ComponentWrapper parentW, boolean b)
- {
- if (b && (debugTimer == null || curDelay != lc.getDebugMillis())) {
- if (debugTimer != null)
- debugTimer.cancel();
-
- TimerTask debugTask = new TimerTask() {
- public void run()
- {
- Display.getDefault ().asyncExec(new Runnable () {
- public void run () {
- grid.paintDebug();
- }
- });
- }
- };
-
- debugTimer = new Timer(true);
- curDelay = lc.getDebugMillis();
- debugTimer.schedule(debugTask, curDelay, curDelay);
-
- ContainerWrapper pCW = parentW.getParent();
- Composite parent = pCW != null ? (Composite) pCW.getComponent() : null;
- if (parent != null)
- parent.layout();
- } else if (!b && debugTimer != null) {
- debugTimer.cancel();
- debugTimer = null;
- }
- }
-
- /** Returns the current debugging state.
- * @return The current debugging state.
- */
- private boolean getDebug()
- {
- return debugTimer != null;
- }
-
- /** Check if something has changed and if so recrete it to the cached objects.
- * @param parent The parent that is the target for this layout manager.
- */
- private final void checkCache(Composite parent)
- {
- if (parent == null)
- return;
-
- checkConstrMap(parent);
-
- ContainerWrapper par = checkParent(parent);
-
- // Check if the grid is valid
- int mc = PlatformDefaults.getModCount();
- if (lastModCount != mc) {
- grid = null;
- lastModCount = mc;
- }
-
- int hash = parent.getSize().hashCode();
- for (Iterator<ComponentWrapper> it = ccMap.keySet().iterator(); it.hasNext();)
- hash += it.next().getLayoutHashCode();
-
- if (hash != lastHash) {
- grid = null;
- lastHash = hash;
- }
-
- setDebug(par, lc.getDebugMillis() > 0);
-
- if (grid == null)
- grid = new Grid(par, lc, rowSpecs, colSpecs, ccMap, callbackList);
- }
-
- private boolean checkConstrMap(Composite parent)
- {
- Control[] comps = parent.getChildren();
- boolean changed = comps.length != scrConstrMap.size();
-
- if (changed == false) {
- for (int i = 0; i < comps.length; i++) {
- Control c = comps[i];
- if (scrConstrMap.get(c) != c.getLayoutData()) {
- changed = true;
- break;
- }
- }
- }
-
- if (changed) {
- scrConstrMap.clear();
- for (int i = 0; i < comps.length; i++) {
- Control c = comps[i];
- setComponentConstraintsImpl(c, c.getLayoutData(), true);
- }
- }
- return changed;
- }
-
- private final ContainerWrapper checkParent(Composite parent)
- {
- if (parent == null)
- return null;
-
- if (cacheParentW == null || cacheParentW.getComponent() != parent)
- cacheParentW = new SwtContainerWrapper(parent);
-
- return cacheParentW;
- }
-
- public float getLayoutAlignmentX(Composite parent)
- {
- return lc != null && lc.getAlignX() != null ? lc.getAlignX().getPixels(1, checkParent(parent), null) : 0;
- }
-
- public float getLayoutAlignmentY(Composite parent)
- {
- return lc != null && lc.getAlignY() != null ? lc.getAlignY().getPixels(1, checkParent(parent), null) : 0;
- }
-
- protected Point computeSize(Composite parent, int wHint, int hHint, boolean flushCache)
- {
- checkCache(parent);
-
- int w = LayoutUtil.getSizeSafe(grid != null ? grid.getWidth() : null, LayoutUtil.PREF);
- int h = LayoutUtil.getSizeSafe(grid != null ? grid.getHeight() : null, LayoutUtil.PREF);
-
- return new Point(w, h);
- }
-
- protected void layout(Composite parent, boolean flushCache)
- {
- checkCache(parent);
-
- Rectangle r = parent.getClientArea();
- int[] b = new int[] {r.x, r.y, r.width, r.height};
-
- final boolean layoutAgain = grid.layout(b, lc.getAlignX(), lc.getAlignY(), getDebug(), true);
-
- if (layoutAgain) {
- grid = null;
- checkCache(parent);
- grid.layout(b, lc.getAlignX(), lc.getAlignY(), getDebug(), false);
- }
- }
-
- protected boolean flushCache(Control control)
- {
- if (lc.isNoCache())
- grid = null;
-
- return true;
- }
-
- // ************************************************
- // Persistence Delegate and Serializable combined.
- // ************************************************
-
- private Object readResolve() throws ObjectStreamException
- {
- return LayoutUtil.getSerializedObject(this);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in));
- }
-
- public void writeExternal(ObjectOutput out) throws IOException
- {
- if (getClass() == MigLayout.class)
- LayoutUtil.writeAsXML(out, this);
- }
+package net.miginfocom.swt; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +import net.miginfocom.layout.*; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.*; +import org.eclipse.swt.widgets.Composite; + +import java.io.*; +import java.util.*; + +/** A very flexbile layout manager. + * <p> + * Read the documentation that came with this layout manager for information on usage. + */ +public final class MigLayout extends Layout implements Externalizable +{ + // ******** Instance part ******** + + /** The component to string constraints mappings. + */ + private final Map<Control, Object> scrConstrMap = new IdentityHashMap<Control, Object>(8); + + /** Hold the serializable text representation of the constraints. + */ + private Object layoutConstraints = "", colConstraints = "", rowConstraints = ""; // Should never be null! + + // ******** Transient part ******** + + private transient ContainerWrapper cacheParentW = null; + + private transient final Map<ComponentWrapper, CC> ccMap = new HashMap<ComponentWrapper, CC>(8); + + private transient LC lc = null; + private transient AC colSpecs = null, rowSpecs = null; + private transient Grid grid = null; + + private transient java.util.Timer debugTimer = null; + private transient long curDelay = -1; + private transient int lastModCount = PlatformDefaults.getModCount(); + private transient int lastHash = -1; + + private transient ArrayList<LayoutCallback> callbackList = null; + + /** Constructor with no constraints. + */ + public MigLayout() + { + this("", "", ""); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "". + */ + public MigLayout(String layoutConstraints) + { + this(layoutConstraints, "", ""); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "". + * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as "". + */ + public MigLayout(String layoutConstraints, String colConstraints) + { + this(layoutConstraints, colConstraints, ""); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as "". + * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as "". + * @param rowConstraints The constraints for the rows in the grid. <code>null</code> will be treated as "". + */ + public MigLayout(String layoutConstraints, String colConstraints, String rowConstraints) + { + setLayoutConstraints(layoutConstraints); + setColumnConstraints(colConstraints); + setRowConstraints(rowConstraints); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint. + */ + public MigLayout(LC layoutConstraints) + { + this(layoutConstraints, null, null); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint. + * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as an empty constraint. + */ + public MigLayout(LC layoutConstraints, AC colConstraints) + { + this(layoutConstraints, colConstraints, null); + } + + /** Constructor. + * @param layoutConstraints The constraints that concern the whole layout. <code>null</code> will be treated as an empty cosntraint. + * @param colConstraints The constraints for the columns in the grid. <code>null</code> will be treated as an empty constraint. + * @param rowConstraints The constraints for the rows in the grid. <code>null</code> will be treated as an empty constraint. + */ + public MigLayout(LC layoutConstraints, AC colConstraints, AC rowConstraints) + { + setLayoutConstraints(layoutConstraints); + setColumnConstraints(colConstraints); + setRowConstraints(rowConstraints); + } + + /** Returns layout constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in + * to the constructor or set with {@link #setLayoutConstraints(Object)}. + * @return The layout constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in + * to the constructor or set with {@link #setLayoutConstraints(Object)}. Never <code>null</code>. + */ + public Object getLayoutConstraints() + { + return layoutConstraints; + } + + /** Sets the layout constraints for the layout manager instance as a String. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param s The layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage. + * @throws RuntimeException if the constaint was not valid. + */ + public void setLayoutConstraints(Object s) + { + if (s == null || s instanceof String) { + s = ConstraintParser.prepare((String) s); + lc = ConstraintParser.parseLayoutConstraint((String) s); + } else if (s instanceof LC) { + lc = (LC) s; + } else { + throw new IllegalArgumentException("Illegal constraint type: " + s.getClass().toString()); + } + layoutConstraints = s; + grid = null; + } + + /** Returns the column layout constraints either as a <code>String</code> or {@link net.miginfocom.layout.AC}. + * @return The column constraints eighter as a <code>String</code> or {@link net.miginfocom.layout.LC} depending what was sent in + * to the constructor or set with {@link #setLayoutConstraints(Object)}. Never <code>null</code>. + */ + public Object getColumnConstraints() + { + return colConstraints; + } + + /** Sets the column layout constraints for the layout manager instance as a String. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The column layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage. + * @throws RuntimeException if the constaint was not valid. + */ + public void setColumnConstraints(Object constr) + { + if (constr == null || constr instanceof String) { + constr = ConstraintParser.prepare((String) constr); + colSpecs = ConstraintParser.parseColumnConstraints((String) constr); + } else if (constr instanceof AC) { + colSpecs = (AC) constr; + } else { + throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString()); + } + colConstraints = constr; + grid = null; + } + + /** Returns the row layout constraints as a String representation. This string is the exact string as set with {@link #setRowConstraints(Object)} + * or sent into the constructor. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @return The row layout constraints as a String representation. Never <code>null</code>. + */ + public Object getRowConstraints() + { + return rowConstraints; + } + + /** Sets the row layout constraints for the layout manager instance as a String. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The row layout constraints as a String representation. <code>null</code> is converted to <code>""</code> for storage. + * @throws RuntimeException if the constaint was not valid. + */ + public void setRowConstraints(Object constr) + { + if (constr == null || constr instanceof String) { + constr = ConstraintParser.prepare((String) constr); + rowSpecs = ConstraintParser.parseRowConstraints((String) constr); + } else if (constr instanceof AC) { + rowSpecs = (AC) constr; + } else { + throw new IllegalArgumentException("Illegal constraint type: " + constr.getClass().toString()); + } + rowConstraints = constr; + grid = null; + } + + /** Returns the component constraints as a String representation. This string is the exact string as set with {@link #setComponentConstraints(org.eclipse.swt.widgets.Control, Object)} + * or set when adding the component to the parent component. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param comp The component to return the constraints for. + * @return The component constraints as a String representation ir <code>null</code> if the component is not registered + * with this layout manager. The returned values is wither a String or a {@link net.miginfocom.layout.CC} + * depending on what constraint was sent in when the component was added. May be <code>null</code>. + */ + public Object getComponentConstraints(Control comp) + { + return scrConstrMap.get(comp); + } + + /** Sets the component constraint for the component that already must be handleded by this layout manager. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The component constraints as a String or {@link net.miginfocom.layout.CC}. <code>null</code> is ok. + * @param comp The component to set the constraints for. + * @throws RuntimeException if the constaint was not valid. + * @throws IllegalArgumentException If the component is not handlering the component. + */ + public void setComponentConstraints(Control comp, Object constr) + { + setComponentConstraintsImpl(comp, constr, false); + } + + /** Sets the component constraint for the component that already must be handleded by this layout manager. + * <p> + * See the class JavaDocs for information on how this string is formatted. + * @param constr The component constraints as a String or {@link net.miginfocom.layout.CC}. <code>null</code> is ok. + * @param comp The component to set the constraints for. + * @throws RuntimeException if the constaint was not valid. + * @throws IllegalArgumentException If the component is not handling the component. + */ + private void setComponentConstraintsImpl(Control comp, Object constr, boolean noCheck) + { + if (noCheck == false && scrConstrMap.containsKey(comp) == false) + throw new IllegalArgumentException("Component must already be added to parent!"); + + ComponentWrapper cw = new SwtComponentWrapper(comp); + + if (constr == null || constr instanceof String) { + String cStr = ConstraintParser.prepare((String) constr); + + scrConstrMap.put(comp, constr); + ccMap.put(cw, ConstraintParser.parseComponentConstraint(cStr)); + + } else if (constr instanceof CC) { + + scrConstrMap.put(comp, constr); + ccMap.put(cw, (CC) constr); + + } else { + throw new IllegalArgumentException("Constraint must be String or ComponentConstraint: " + constr.getClass().toString()); + } + grid = null; + } + + /** Returns if this layout manager is currently managing this component. + * @param c The component to check. If <code>null</code> then <code>false</code> will be returned. + * @return If this layout manager is currently managing this component. + */ + public boolean isManagingComponent(Control c) + { + return scrConstrMap.containsKey(c); + } + + /** Adds the callback function that will be called at different stages of the layout cylce. + * @param callback The callback. Not <code>null</code>. + */ + public void addLayoutCallback(LayoutCallback callback) + { + if (callback == null) + throw new NullPointerException(); + + if (callbackList == null) + callbackList = new ArrayList<LayoutCallback>(1); + + callbackList.add(callback); + } + + /** Removes the callback if it exists. + * @param callback The callback. May be <code>null</code>. + */ + public void removeLayoutCallback(LayoutCallback callback) + { + if (callbackList != null) + callbackList.remove(callback); + } + + /** Sets the debugging state for this layout manager instance. If debug is turned on a timer will repaint the last laid out parent + * with debug information on top. + * <p> + * Red fill and dashed darked red outline is used to indicate occupied cells in the grid. Blue dashed outline indicate indicate + * component bounds set. + * <p> + * Note that debug can also be set on the layout constraints. There it will be persisted. The calue set here will not. See the class + * JavaDocs for information. + * @param b <code>true</code> means debug is turned on. + */ + private synchronized void setDebug(final ComponentWrapper parentW, boolean b) + { + if (b && (debugTimer == null || curDelay != lc.getDebugMillis())) { + if (debugTimer != null) + debugTimer.cancel(); + + TimerTask debugTask = new TimerTask() { + public void run() + { + Display.getDefault ().asyncExec(new Runnable () { + public void run () { + grid.paintDebug(); + } + }); + } + }; + + debugTimer = new Timer(true); + curDelay = lc.getDebugMillis(); + debugTimer.schedule(debugTask, curDelay, curDelay); + + ContainerWrapper pCW = parentW.getParent(); + Composite parent = pCW != null ? (Composite) pCW.getComponent() : null; + if (parent != null) + parent.layout(); + } else if (!b && debugTimer != null) { + debugTimer.cancel(); + debugTimer = null; + } + } + + /** Returns the current debugging state. + * @return The current debugging state. + */ + private boolean getDebug() + { + return debugTimer != null; + } + + /** Check if something has changed and if so recrete it to the cached objects. + * @param parent The parent that is the target for this layout manager. + */ + private final void checkCache(Composite parent) + { + if (parent == null) + return; + + checkConstrMap(parent); + + ContainerWrapper par = checkParent(parent); + + // Check if the grid is valid + int mc = PlatformDefaults.getModCount(); + if (lastModCount != mc) { + grid = null; + lastModCount = mc; + } + + int hash = parent.getSize().hashCode(); + for (Iterator<ComponentWrapper> it = ccMap.keySet().iterator(); it.hasNext();) + hash += it.next().getLayoutHashCode(); + + if (hash != lastHash) { + grid = null; + lastHash = hash; + } + + setDebug(par, lc.getDebugMillis() > 0); + + if (grid == null) + grid = new Grid(par, lc, rowSpecs, colSpecs, ccMap, callbackList); + } + + private boolean checkConstrMap(Composite parent) + { + Control[] comps = parent.getChildren(); + boolean changed = comps.length != scrConstrMap.size(); + + if (changed == false) { + for (int i = 0; i < comps.length; i++) { + Control c = comps[i]; + if (scrConstrMap.get(c) != c.getLayoutData()) { + changed = true; + break; + } + } + } + + if (changed) { + scrConstrMap.clear(); + for (int i = 0; i < comps.length; i++) { + Control c = comps[i]; + setComponentConstraintsImpl(c, c.getLayoutData(), true); + } + } + return changed; + } + + private final ContainerWrapper checkParent(Composite parent) + { + if (parent == null) + return null; + + if (cacheParentW == null || cacheParentW.getComponent() != parent) + cacheParentW = new SwtContainerWrapper(parent); + + return cacheParentW; + } + + public float getLayoutAlignmentX(Composite parent) + { + return lc != null && lc.getAlignX() != null ? lc.getAlignX().getPixels(1, checkParent(parent), null) : 0; + } + + public float getLayoutAlignmentY(Composite parent) + { + return lc != null && lc.getAlignY() != null ? lc.getAlignY().getPixels(1, checkParent(parent), null) : 0; + } + + protected Point computeSize(Composite parent, int wHint, int hHint, boolean flushCache) + { + checkCache(parent); + + int w = LayoutUtil.getSizeSafe(grid != null ? grid.getWidth() : null, LayoutUtil.PREF); + int h = LayoutUtil.getSizeSafe(grid != null ? grid.getHeight() : null, LayoutUtil.PREF); + + return new Point(w, h); + } + + protected void layout(Composite parent, boolean flushCache) + { + checkCache(parent); + + Rectangle r = parent.getClientArea(); + int[] b = new int[] {r.x, r.y, r.width, r.height}; + + final boolean layoutAgain = grid.layout(b, lc.getAlignX(), lc.getAlignY(), getDebug(), true); + + if (layoutAgain) { + grid = null; + checkCache(parent); + grid.layout(b, lc.getAlignX(), lc.getAlignY(), getDebug(), false); + } + } + + protected boolean flushCache(Control control) + { + if (lc.isNoCache()) + grid = null; + + return true; + } + + // ************************************************ + // Persistence Delegate and Serializable combined. + // ************************************************ + + private Object readResolve() throws ObjectStreamException + { + return LayoutUtil.getSerializedObject(this); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + LayoutUtil.setSerializedObject(this, LayoutUtil.readAsXML(in)); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + if (getClass() == MigLayout.class) + LayoutUtil.writeAsXML(out, this); + } }
\ No newline at end of file diff --git a/prototypes/miglayout/net/miginfocom/swt/SwtComponentWrapper.java b/prototypes/miglayout/net/miginfocom/swt/SwtComponentWrapper.java index aa7647a7..e994f790 100644 --- a/prototypes/miglayout/net/miginfocom/swt/SwtComponentWrapper.java +++ b/prototypes/miglayout/net/miginfocom/swt/SwtComponentWrapper.java @@ -1,359 +1,359 @@ -package net.miginfocom.swt;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-import net.miginfocom.layout.ComponentWrapper;
-import net.miginfocom.layout.ContainerWrapper;
-import net.miginfocom.layout.PlatformDefaults;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- */
-public class SwtComponentWrapper implements ComponentWrapper
-{
- /** Debug color for component bounds outline.
- */
- private static Color DB_COMP_OUTLINE = new Color(Display.getCurrent(), 0, 0, 200);
-
- private static boolean vp = false;
- private static boolean mz = false;
-
- private final Control c;
- private int compType = TYPE_UNSET;
-
- public SwtComponentWrapper(Control c)
- {
- this.c = c;
- }
-
- public final int getBaseline(int width, int height)
- {
- return -1;
- }
-
- public final Object getComponent()
- {
- return c;
- }
-
- public final float getPixelUnitFactor(boolean isHor)
- {
- switch (PlatformDefaults.getLogicalPixelBase()) {
- case PlatformDefaults.BASE_FONT_SIZE:
- GC gc = new GC(c);
- FontMetrics fm = gc.getFontMetrics();
- float f = isHor ? fm.getAverageCharWidth() / 5f : fm.getHeight() / 13f;
- gc.dispose();
- return f;
-
- case PlatformDefaults.BASE_SCALE_FACTOR:
- Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor();
- if (s != null)
- return s.floatValue();
- return (isHor ? getHorizontalScreenDPI() : getVerticalScreenDPI()) / (float) PlatformDefaults.getDefaultDPI();
-
- default:
- return 1f;
- }
- }
-
-// /** Cache.
-// */
-// private final static IdentityHashMap<FontMetrics, Point.Float> FM_MAP2 = new IdentityHashMap<FontMetrics, Point.Float>(4);
-// private final static Font SUBST_FONT2 = new Font("sansserif", Font.PLAIN, 11);
-//
-// public float getDialogUnit(boolean isHor)
-// {
-// Font font = c.getFont();
-// FontMetrics fm = c.getFontMetrics(font != null ? font : SUBST_FONT2);
-// Point.Float dluP = FM_MAP2.get(fm);
-// if (dluP == null) {
-// float w = fm.charWidth('X') / 4f;
-// int ascent = fm.getAscent();
-// float h = (ascent > 14 ? ascent : ascent + (15 - ascent) / 3) / 8f;
-//
-// dluP = new Point.Float(w, h);
-// FM_MAP2.put(fm, dluP);
-// }
-// return isHor ? dluP.x : dluP.y;
-// }
-
- public final int getX()
- {
- return c.getLocation().x;
- }
-
- public final int getY()
- {
- return c.getLocation().y;
- }
-
- public final int getWidth()
- {
- return c.getSize().x;
- }
-
- public final int getHeight()
- {
- return c.getSize().y;
- }
-
- public final int getScreenLocationX()
- {
- return c.toDisplay(0, 0).x;
- }
-
- public final int getScreenLocationY()
- {
- return c.toDisplay(0, 0).y;
- }
-
- public final int getMinimumHeight()
- {
- return mz ? 0 : computeSize(false).y;
- }
-
- public final int getMinimumWidth()
- {
- return mz ? 0 : computeSize(true).x;
- }
-
- public final int getPreferredHeight()
- {
- return computeSize(false).y;
- }
-
- public final int getPreferredWidth()
- {
- return computeSize(true).x;
- }
-
- public final int getMaximumHeight()
- {
- return Short.MAX_VALUE;
- }
-
- public final int getMaximumWidth()
- {
- return Short.MAX_VALUE;
- }
-
- private final Point computeSize(boolean h)
- {
- Point p = c.getSize();
- int wHint = (h || p.x <= 0) ? SWT.DEFAULT : p.x;
- int hHint = (!h || p.y <= 0) ? SWT.DEFAULT : p.y;
-
- if (wHint != SWT.DEFAULT || hHint != SWT.DEFAULT) {
- int trim = 0;
- if (c instanceof Scrollable) {
- Rectangle rect = ((Scrollable) c).computeTrim (0, 0, 0, 0);
- trim = h ? rect.height : rect.width;
- } else {
- trim = (c.getBorderWidth () << 1);
- }
- if (wHint == SWT.DEFAULT) {
- hHint = Math.max (0, hHint - trim);
- } else {
- wHint = Math.max (0, wHint - trim);
- }
- }
-
- return c.computeSize(wHint, hHint);
- }
-
- public final ContainerWrapper getParent()
- {
- return new SwtContainerWrapper(c.getParent());
- }
-
- public int getHorizontalScreenDPI()
- {
- return c.getDisplay().getDPI().x;
- }
-
- public int getVerticalScreenDPI()
- {
- return c.getDisplay().getDPI().y;
- }
-
- public final int getScreenWidth()
- {
- return c.getDisplay().getBounds().width;
- }
-
- public final int getScreenHeight()
- {
- return c.getDisplay().getBounds().height;
- }
-
- public final boolean hasBaseline()
- {
- return false;
- }
-
- public final String getLinkId()
- {
- return null;
- }
-
- public final void setBounds(int x, int y, int width, int height)
- {
- c.setBounds(x, y, width, height);
- }
-
- public boolean isVisible()
- {
- return c.getVisible();
- }
-
- public final int[] getVisualPadding()
- {
- return null;
- }
-
- public final static boolean isUseVisualPadding()
- {
- return vp;
- }
-
- public final static void setUseVisualPadding(boolean b)
- {
- vp = b;
- }
-
- /** Sets if minimum size for SWT components should be preferred size (default, false) or 0.
- * @return <code>true</code> means minimum size is 0.
- */
- public static boolean isMinimumSizeZero()
- {
- return mz;
- }
-
- /** Sets if minimum size for SWT components should be preferred size (default, false) or 0.
- * @param b <code>true</code> means minimum size is 0.
- */
- public static void setMinimumSizeZero(boolean b)
- {
- mz = b;
- }
-
- public int getLayoutHashCode()
- {
- if (c.isDisposed())
- return -1;
-
- Point sz = c.getSize();
- Point p = c.computeSize(sz.x > 0 ? sz.x : SWT.DEFAULT, SWT.DEFAULT, false);
- int h = p.x + (p.y << 12) + (sz.x << 22) + (sz.y << 16);
-
- if (c.isVisible())
- h |= (1 << 25);
-
- String id = getLinkId();
- if (id != null)
- h += id.hashCode();
- return h;
- }
-
- public final void paintDebugOutline()
- {
- if (c.isDisposed())
- return;
-
- GC gc = new GC(c);
-
- gc.setLineJoin(SWT.JOIN_MITER);
- gc.setLineCap(SWT.CAP_SQUARE);
- gc.setLineStyle(SWT.LINE_DOT);
-
- gc.setForeground(DB_COMP_OUTLINE);
- gc.drawRectangle(0, 0, getWidth() - 1, getHeight() - 1);
-
- gc.dispose();
- }
-
- public int getComponetType(boolean disregardScrollPane)
- {
- if (compType == TYPE_UNSET)
- compType = checkType();
-
- return compType;
- }
-
- private final int checkType()
- {
- int s = c.getStyle();
-
- if (c instanceof Text) {
- return (s & SWT.MULTI) > 0 ? TYPE_TEXT_AREA : TYPE_TEXT_FIELD;
- } else if (c instanceof Label) {
- return (s & SWT.SEPARATOR) > 0 ? TYPE_SEPARATOR : TYPE_LABEL;
- } else if (c instanceof Button) {
- if ((s & SWT.CHECK) > 0 || (s & SWT.RADIO) > 0)
- return TYPE_CHECK_BOX;
- return TYPE_BUTTON;
- } else if (c instanceof Canvas) {
- return TYPE_PANEL;
- } else if (c instanceof List) {
- return TYPE_LIST;
- } else if (c instanceof Table) {
- return TYPE_TABLE;
- } else if (c instanceof Spinner) {
- return TYPE_SPINNER;
- } else if (c instanceof ProgressBar) {
- return TYPE_PROGRESS_BAR;
- } else if (c instanceof Slider) {
- return TYPE_SLIDER;
- } else if (c instanceof Composite) { // only AWT components is not containers.
- return TYPE_CONTAINER;
- }
- return TYPE_UNKNOWN;
- }
-
- public final int hashCode()
- {
- return getComponent().hashCode();
- }
-
- public final boolean equals(Object o)
- {
- if (o == null || o instanceof ComponentWrapper == false)
- return false;
-
- return getComponent().equals(((ComponentWrapper) o).getComponent());
- }
-}
+package net.miginfocom.swt; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +import net.miginfocom.layout.ComponentWrapper; +import net.miginfocom.layout.ContainerWrapper; +import net.miginfocom.layout.PlatformDefaults; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.widgets.*; + +/** + */ +public class SwtComponentWrapper implements ComponentWrapper +{ + /** Debug color for component bounds outline. + */ + private static Color DB_COMP_OUTLINE = new Color(Display.getCurrent(), 0, 0, 200); + + private static boolean vp = false; + private static boolean mz = false; + + private final Control c; + private int compType = TYPE_UNSET; + + public SwtComponentWrapper(Control c) + { + this.c = c; + } + + public final int getBaseline(int width, int height) + { + return -1; + } + + public final Object getComponent() + { + return c; + } + + public final float getPixelUnitFactor(boolean isHor) + { + switch (PlatformDefaults.getLogicalPixelBase()) { + case PlatformDefaults.BASE_FONT_SIZE: + GC gc = new GC(c); + FontMetrics fm = gc.getFontMetrics(); + float f = isHor ? fm.getAverageCharWidth() / 5f : fm.getHeight() / 13f; + gc.dispose(); + return f; + + case PlatformDefaults.BASE_SCALE_FACTOR: + Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor(); + if (s != null) + return s.floatValue(); + return (isHor ? getHorizontalScreenDPI() : getVerticalScreenDPI()) / (float) PlatformDefaults.getDefaultDPI(); + + default: + return 1f; + } + } + +// /** Cache. +// */ +// private final static IdentityHashMap<FontMetrics, Point.Float> FM_MAP2 = new IdentityHashMap<FontMetrics, Point.Float>(4); +// private final static Font SUBST_FONT2 = new Font("sansserif", Font.PLAIN, 11); +// +// public float getDialogUnit(boolean isHor) +// { +// Font font = c.getFont(); +// FontMetrics fm = c.getFontMetrics(font != null ? font : SUBST_FONT2); +// Point.Float dluP = FM_MAP2.get(fm); +// if (dluP == null) { +// float w = fm.charWidth('X') / 4f; +// int ascent = fm.getAscent(); +// float h = (ascent > 14 ? ascent : ascent + (15 - ascent) / 3) / 8f; +// +// dluP = new Point.Float(w, h); +// FM_MAP2.put(fm, dluP); +// } +// return isHor ? dluP.x : dluP.y; +// } + + public final int getX() + { + return c.getLocation().x; + } + + public final int getY() + { + return c.getLocation().y; + } + + public final int getWidth() + { + return c.getSize().x; + } + + public final int getHeight() + { + return c.getSize().y; + } + + public final int getScreenLocationX() + { + return c.toDisplay(0, 0).x; + } + + public final int getScreenLocationY() + { + return c.toDisplay(0, 0).y; + } + + public final int getMinimumHeight() + { + return mz ? 0 : computeSize(false).y; + } + + public final int getMinimumWidth() + { + return mz ? 0 : computeSize(true).x; + } + + public final int getPreferredHeight() + { + return computeSize(false).y; + } + + public final int getPreferredWidth() + { + return computeSize(true).x; + } + + public final int getMaximumHeight() + { + return Short.MAX_VALUE; + } + + public final int getMaximumWidth() + { + return Short.MAX_VALUE; + } + + private final Point computeSize(boolean h) + { + Point p = c.getSize(); + int wHint = (h || p.x <= 0) ? SWT.DEFAULT : p.x; + int hHint = (!h || p.y <= 0) ? SWT.DEFAULT : p.y; + + if (wHint != SWT.DEFAULT || hHint != SWT.DEFAULT) { + int trim = 0; + if (c instanceof Scrollable) { + Rectangle rect = ((Scrollable) c).computeTrim (0, 0, 0, 0); + trim = h ? rect.height : rect.width; + } else { + trim = (c.getBorderWidth () << 1); + } + if (wHint == SWT.DEFAULT) { + hHint = Math.max (0, hHint - trim); + } else { + wHint = Math.max (0, wHint - trim); + } + } + + return c.computeSize(wHint, hHint); + } + + public final ContainerWrapper getParent() + { + return new SwtContainerWrapper(c.getParent()); + } + + public int getHorizontalScreenDPI() + { + return c.getDisplay().getDPI().x; + } + + public int getVerticalScreenDPI() + { + return c.getDisplay().getDPI().y; + } + + public final int getScreenWidth() + { + return c.getDisplay().getBounds().width; + } + + public final int getScreenHeight() + { + return c.getDisplay().getBounds().height; + } + + public final boolean hasBaseline() + { + return false; + } + + public final String getLinkId() + { + return null; + } + + public final void setBounds(int x, int y, int width, int height) + { + c.setBounds(x, y, width, height); + } + + public boolean isVisible() + { + return c.getVisible(); + } + + public final int[] getVisualPadding() + { + return null; + } + + public final static boolean isUseVisualPadding() + { + return vp; + } + + public final static void setUseVisualPadding(boolean b) + { + vp = b; + } + + /** Sets if minimum size for SWT components should be preferred size (default, false) or 0. + * @return <code>true</code> means minimum size is 0. + */ + public static boolean isMinimumSizeZero() + { + return mz; + } + + /** Sets if minimum size for SWT components should be preferred size (default, false) or 0. + * @param b <code>true</code> means minimum size is 0. + */ + public static void setMinimumSizeZero(boolean b) + { + mz = b; + } + + public int getLayoutHashCode() + { + if (c.isDisposed()) + return -1; + + Point sz = c.getSize(); + Point p = c.computeSize(sz.x > 0 ? sz.x : SWT.DEFAULT, SWT.DEFAULT, false); + int h = p.x + (p.y << 12) + (sz.x << 22) + (sz.y << 16); + + if (c.isVisible()) + h |= (1 << 25); + + String id = getLinkId(); + if (id != null) + h += id.hashCode(); + return h; + } + + public final void paintDebugOutline() + { + if (c.isDisposed()) + return; + + GC gc = new GC(c); + + gc.setLineJoin(SWT.JOIN_MITER); + gc.setLineCap(SWT.CAP_SQUARE); + gc.setLineStyle(SWT.LINE_DOT); + + gc.setForeground(DB_COMP_OUTLINE); + gc.drawRectangle(0, 0, getWidth() - 1, getHeight() - 1); + + gc.dispose(); + } + + public int getComponetType(boolean disregardScrollPane) + { + if (compType == TYPE_UNSET) + compType = checkType(); + + return compType; + } + + private final int checkType() + { + int s = c.getStyle(); + + if (c instanceof Text) { + return (s & SWT.MULTI) > 0 ? TYPE_TEXT_AREA : TYPE_TEXT_FIELD; + } else if (c instanceof Label) { + return (s & SWT.SEPARATOR) > 0 ? TYPE_SEPARATOR : TYPE_LABEL; + } else if (c instanceof Button) { + if ((s & SWT.CHECK) > 0 || (s & SWT.RADIO) > 0) + return TYPE_CHECK_BOX; + return TYPE_BUTTON; + } else if (c instanceof Canvas) { + return TYPE_PANEL; + } else if (c instanceof List) { + return TYPE_LIST; + } else if (c instanceof Table) { + return TYPE_TABLE; + } else if (c instanceof Spinner) { + return TYPE_SPINNER; + } else if (c instanceof ProgressBar) { + return TYPE_PROGRESS_BAR; + } else if (c instanceof Slider) { + return TYPE_SLIDER; + } else if (c instanceof Composite) { // only AWT components is not containers. + return TYPE_CONTAINER; + } + return TYPE_UNKNOWN; + } + + public final int hashCode() + { + return getComponent().hashCode(); + } + + public final boolean equals(Object o) + { + if (o == null || o instanceof ComponentWrapper == false) + return false; + + return getComponent().equals(((ComponentWrapper) o).getComponent()); + } +} diff --git a/prototypes/miglayout/net/miginfocom/swt/SwtContainerWrapper.java b/prototypes/miglayout/net/miginfocom/swt/SwtContainerWrapper.java index 033bb2bf..b27dbe84 100644 --- a/prototypes/miglayout/net/miginfocom/swt/SwtContainerWrapper.java +++ b/prototypes/miglayout/net/miginfocom/swt/SwtContainerWrapper.java @@ -1,112 +1,112 @@ -package net.miginfocom.swt;
-/*
- * License (BSD):
- * ==============
- *
- * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * @version 1.0
- * @author Mikael Grev, MiG InfoCom AB
- * Date: 2006-sep-08
- */
-
-import net.miginfocom.layout.ComponentWrapper;
-import net.miginfocom.layout.ContainerWrapper;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.SWT;
-
-/**
- */
-public final class SwtContainerWrapper extends SwtComponentWrapper implements ContainerWrapper
-{
- public SwtContainerWrapper(Composite c)
- {
- super(c);
- }
-
- public ComponentWrapper[] getComponents()
- {
- Composite c = (Composite) getComponent();
- Control[] cons = c.getChildren();
- ComponentWrapper[] cws = new ComponentWrapper[cons.length];
- for (int i = 0; i < cws.length; i++)
- cws[i] = new SwtComponentWrapper(cons[i]);
- return cws;
- }
-
- public int getComponentCount()
- {
- return ((Composite) getComponent()).getChildren().length;
- }
-
- public Object getLayout()
- {
- return ((Composite) getComponent()).getLayout();
- }
-
- public final boolean isLeftToRight()
- {
- return (((Composite) getComponent()).getStyle() & SWT.LEFT_TO_RIGHT) > 0;
- }
-
- public final void paintDebugCell(int x, int y, int width, int height)
- {
- // A Composite can not draw above its children, so the cells can not be painted.
-
-// if (c.isDisposed())
-// return;
-// GC gc = new GC(c);
-//
-// gc.setLineStyle(SWT.LINE_DASHDOTDOT);
-// gc.setLineJoin(SWT.JOIN_MITER);
-// gc.setLineCap(SWT.CAP_SQUARE);
-//
-// gc.setBackground(DB_CELL_BG);
-// gc.fillRectangle(x, y, width, height);
-//
-// gc.setForeground(DB_CELL_OUTLINE);
-// gc.drawRectangle(x, y, width - 1, height - 1);
-//
-// gc.dispose();
- }
-
- public int getComponetType(boolean disregardScrollPane)
- {
- return TYPE_CONTAINER;
- }
-
-
- public int getLayoutHashCode()
- {
- int h = super.getLayoutHashCode();
-
- if (isLeftToRight())
- h |= (1 << 26);
-
- return h;
- }
-}
+package net.miginfocom.swt; +/* + * License (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 1.0 + * @author Mikael Grev, MiG InfoCom AB + * Date: 2006-sep-08 + */ + +import net.miginfocom.layout.ComponentWrapper; +import net.miginfocom.layout.ContainerWrapper; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.SWT; + +/** + */ +public final class SwtContainerWrapper extends SwtComponentWrapper implements ContainerWrapper +{ + public SwtContainerWrapper(Composite c) + { + super(c); + } + + public ComponentWrapper[] getComponents() + { + Composite c = (Composite) getComponent(); + Control[] cons = c.getChildren(); + ComponentWrapper[] cws = new ComponentWrapper[cons.length]; + for (int i = 0; i < cws.length; i++) + cws[i] = new SwtComponentWrapper(cons[i]); + return cws; + } + + public int getComponentCount() + { + return ((Composite) getComponent()).getChildren().length; + } + + public Object getLayout() + { + return ((Composite) getComponent()).getLayout(); + } + + public final boolean isLeftToRight() + { + return (((Composite) getComponent()).getStyle() & SWT.LEFT_TO_RIGHT) > 0; + } + + public final void paintDebugCell(int x, int y, int width, int height) + { + // A Composite can not draw above its children, so the cells can not be painted. + +// if (c.isDisposed()) +// return; +// GC gc = new GC(c); +// +// gc.setLineStyle(SWT.LINE_DASHDOTDOT); +// gc.setLineJoin(SWT.JOIN_MITER); +// gc.setLineCap(SWT.CAP_SQUARE); +// +// gc.setBackground(DB_CELL_BG); +// gc.fillRectangle(x, y, width, height); +// +// gc.setForeground(DB_CELL_OUTLINE); +// gc.drawRectangle(x, y, width - 1, height - 1); +// +// gc.dispose(); + } + + public int getComponetType(boolean disregardScrollPane) + { + return TYPE_CONTAINER; + } + + + public int getLayoutHashCode() + { + int h = super.getLayoutHashCode(); + + if (isLeftToRight()) + h |= (1 << 26); + + return h; + } +} diff --git a/src/build.bat b/src/build.bat index 9fef1825..6928adfe 100644 --- a/src/build.bat +++ b/src/build.bat @@ -1,22 +1,22 @@ -@echo off
-
-rem We use FPC to found out the Platform and OS to create a lib output path
-fpc -iTP > tmpvar
-set /p myplatform= < tmpvar
-fpc -iTO > tmpvar
-set /p myos= < tmpvar
-del tmpvar
-
-if exist ..\lib\%myplatform%-%myos%\nul.x goto exists
-
-echo Creating missing directory ..\lib\%myplatform%-%myos%
-mkdir ..\lib\%myplatform%-%myos%
-goto end
-
-:exists
-echo "You've got the correct output lib directory"
-
-:end
-
-fpc -dRELEASE -dGDI @extrafpc.cfg corelib\gdi\fpgui_toolkit.pas
-
+@echo off + +rem We use FPC to found out the Platform and OS to create a lib output path +fpc -iTP > tmpvar +set /p myplatform= < tmpvar +fpc -iTO > tmpvar +set /p myos= < tmpvar +del tmpvar + +if exist ..\lib\%myplatform%-%myos%\nul.x goto exists + +echo Creating missing directory ..\lib\%myplatform%-%myos% +mkdir ..\lib\%myplatform%-%myos% +goto end + +:exists +echo "You've got the correct output lib directory" + +:end + +fpc -dRELEASE -dGDI @extrafpc.cfg corelib\gdi\fpgui_toolkit.pas + diff --git a/src/corelib/gdi/fpg_oledragdrop.pas b/src/corelib/gdi/fpg_oledragdrop.pas index 36eed0a5..11798bb6 100644 --- a/src/corelib/gdi/fpg_oledragdrop.pas +++ b/src/corelib/gdi/fpg_oledragdrop.pas @@ -1,1074 +1,1074 @@ -{
- fpGUI - Free Pascal GUI Toolkit
-
- Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this
- distribution, for details of the copyright.
-
- See the file COPYING.modifiedLGPL, included in this distribution,
- for details about redistributing fpGUI.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- Description:
- This unit implements the OLE Drag-n-Drop functionality of Windows.
- This unit is implemented based on the articles posted on
- http://www.catch22.net/tuts/dragdrop/
-}
-unit fpg_OLEDragDrop;
-
-{$mode delphi}{$H+}
-
-interface
-
-uses
- Windows, Classes, ActiveX, ShellAPI, fpg_base;
-
-const
- CFSTR_FILENAMEMAPA = 'FileNameMap'; { CF_FILENAMEMAPA }
- CFSTR_FILENAMEMAP = CFSTR_FILENAMEMAPA;
- CFSTR_FILEDESCRIPTORA = 'FileGroupDescriptor'; { CF_FILEGROUPDESCRIPTORA }
- CFSTR_FILEDESCRIPTOR = CFSTR_FILEDESCRIPTORA;
- CFSTR_FILECONTENTS = 'FileContents'; { CF_FILECONTENTS }
-
-type
- TfpgOLEFormatEtcList = class(TList)
- private
- function GetFormatEtc(Index: Integer): PFormatEtc;
- protected
- procedure Notify(Ptr: Pointer; Action: TListNotification); override;
- public
- constructor CreateCopy(AFormatEtcList: TfpgOLEFormatEtcList);
- property FormatEtc[Index: Integer]: PFormatEtc read GetFormatEtc; default;
- end;
-
-
- TfpgOLEStgMediumList = class(TList)
- private
- function GetStgMedium(Index: Integer): PStgMedium;
- protected
- procedure Notify(Ptr: Pointer; Action: TListNotification); override;
- public
- property StgMedium[Index: Integer]: PStgMedium read GetStgMedium; default;
- end;
-
-
- TfpgOLEDropSource = class(TInterfacedObject, IDropSource)
- private
- { IDropSource }
- {$IF FPC_FULLVERSION>=20601}
- function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: DWORD):HResult; StdCall;
- function GiveFeedback(dwEffect: DWORD): HResult; StdCall;
- {$ELSE}
- function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: Longint): HResult; stdcall;
- function GiveFeedback(dwEffect: longint): HResult; stdcall;
- {$ENDIF}
- end;
-
-
- TfpgOLEDragDropEffect = (deNone, deCopy, deMove, deLink);
- TfpgOLEDragEnterEvent = procedure(Sender: TObject; DataObj: IDataObject; KeyState: Longint; PT: TPoint; var Effect: DWORD) of object;
- TfpgOLEDragOverEvent = procedure(Sender: TObject; KeyState: Longint; PT: TPoint; var Effect: TfpgOLEDragDropEffect) of object;
- TfpgOLEDragDropEvent = procedure(Sender: TObject; DataObj: IDataObject; KeyState: Longint; PT: TPoint; Effect: TfpgOLEDragDropEffect) of object;
-
-
- TfpgOLEDropTarget = class(TObject, IInterface, IDropTarget)
- private
- FDropTarget: TfpgWindowBase;
- FRegistered: Boolean;
- FOnDragEnter: TfpgOLEDragEnterEvent;
- FOnDragOver: TfpgOLEDragOverEvent;
- FOnDragLeave: TNotifyEvent;
- FOnDragDrop: TfpgOLEDragDropEvent;
- private
- { IInterface }
- function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: TGuid; out obj): LongInt; stdcall;
- function _AddRef: longint; stdcall;
- function _Release: longint; stdcall;
- { IDropTarget }
- function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
- function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult; stdcall;
- function DragLeave: HResult; stdcall;
- function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult; stdcall;
- protected
- procedure DoDragEnter(DataObj: IDataObject; KeyState: Longint; PT: TPoint; var Effect: DWORD); virtual;
- procedure DoDragOver(KeyState: Longint; PT: TPoint; var Effect: TfpgOLEDragDropEffect); virtual;
- procedure DoDragLeave;
- procedure DoDragDrop(DataObj: IDataObject; KeyState: Longint; PT: TPoint; Effect: TfpgOLEDragDropEffect); virtual;
- public
- property OnDragEnter: TfpgOLEDragEnterEvent read FOnDragEnter write FOnDragEnter;
- property OnDragOver: TfpgOLEDragOverEvent read FOnDragOver write FOnDragOver;
- property OnDragLeave: TNotifyEvent read FOnDragLeave write FOnDragLeave;
- property OnDragDrop: TfpgOLEDragDropEvent read FOnDragDrop write FOnDragDrop;
- public
- constructor Create(ADropTargetWidget: TfpgWindowBase); reintroduce; { Actually a TfpgWidget }
- destructor Destroy; override;
- procedure RegisterDragDrop;
- procedure RevokeDragDrop;
- property DropTarget: TfpgWindowBase read FDropTarget;
- end;
-
-
- TfpgOLEDataObject = class(TInterfacedObject, IDataObject)
- private
- FFormatEtcList: TfpgOLEFormatEtcList;
- FStgMediumList: TfpgOLEStgMediumList;
- function LookupFormatEtc(AFormat: TFormatEtc): Integer;
- protected
- { IDataObject }
- function GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult; stdcall;
- function GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium): HResult; stdcall;
- function QueryGetData(const formatetc: TFormatEtc): HResult; stdcall;
- function GetCanonicalFormatEtc(const formatetc: TFormatEtc; out formatetcOut: TFormatEtc): HResult; stdcall;
- function SetData(const formatetc: TFormatEtc; const medium: TStgMedium; fRelease: BOOL): HResult; stdcall;
- function EnumFormatEtc(dwDirection: DWORD; out enumFormatEtc: IEnumFormatEtc): HResult; stdcall;
- function DAdvise(const formatetc: TFormatEtc; advf: DWORD; const advSink: IAdviseSink; out dwConnection: DWORD): HResult; stdcall;
- function DUnadvise(dwConnection: DWORD): HResult; stdcall;
- function EnumDAdvise(out enumAdvise: IEnumStatData): HResult; stdcall;
- public
- constructor Create; overload;
- constructor Create(AFormatEtcList: TfpgOLEFormatEtcList); overload;
- destructor Destroy; override;
- property FormatEtcList: TfpgOLEFormatEtcList read FFormatEtcList;
- property StgMediumList: TfpgOLEStgMediumList read FStgMediumList;
- end;
-
-
- TfpgOLEEnumFormatEtc = class(TInterfacedObject, IEnumFORMATETC)
- private
- FFormatEtcList: TfpgOLEFormatEtcList;
- FIndex: Integer;
- protected
- { IEnumFORMATETC }
- function Next(celt: ULong; out elt:FormatEtc; pceltFetched: pULong=nil): HResult; stdcall;
- function Skip(celt: ULong): HResult; stdcall;
- function Reset: HResult; stdcall;
- function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
- public
- constructor Create(AFormatEtcList: TfpgOLEFormatEtcList);
- destructor Destroy; override;
- end;
-
-
- TDragFilesSource = class(TObject)
- private
- FFileNames: TStrings;
- FAliasFileNames: TStrings;
- function GetAliasFileNames: TStrings;
- function GetSourceFileNames: TStrings;
- procedure SetAliasFileNames(const Value: TStrings);
- procedure SetSourceFileNames(const Value: TStrings);
- public
- constructor Create;
- destructor Destroy; override;
- procedure Execute;
- property SourceFileNames: TStrings read GetSourceFileNames write SetSourceFileNames;
- property AliasFileNames: TStrings read GetAliasFileNames write SetAliasFileNames;
- end;
-
-
- TDragAcceptFilesEvent = function(Sender: TObject; FileNames: TStrings): Boolean of object;
- TDragAcceptPositionEvent = function(Sender: TObject; PT: TPoint): Boolean of object;
- TDropFilesEvent = procedure(Sender: TObject; PT: TPoint; FileNames: TStrings) of object;
-
-
- TDragFilesTarget = class(TfpgOLEDropTarget)
- private
- FDragAcceptFiles: Boolean;
- FOnDragAcceptFiles: TDragAcceptFilesEvent;
- FOnDragAcceptPosition: TDragAcceptPositionEvent;
- FOnDropFiles: TDropFilesEvent;
- procedure GetFileNamesFromDropHandle(DropHandle: HDROP; SL: TStrings);
- procedure StreamToFile(Stream: IStream; const FileName: string);
- protected
- function DoDragAcceptFiles(DataObj: IDataObject): Boolean;
- function DoDragAcceptPosition(PT: TPoint): Boolean;
- procedure DoDropFiles(DataObj: IDataObject; PT: TPoint);
- procedure DoDragEnter(DataObj: IDataObject; KeyState: Longint; PT: TPoint; var Effect: DWORD); override;
- procedure DoDragOver(KeyState: Longint; PT: TPoint; var Effect: TfpgOLEDragDropEffect); override;
- procedure DoDragDrop(DataObj: IDataObject; KeyState: Longint; PT: TPoint; Effect: TfpgOLEDragDropEffect); override;
- public
- property OnDragAcceptFiles: TDragAcceptFilesEvent read FOnDragAcceptFiles write FOnDragAcceptFiles;
- property OnDragAcceptPosition: TDragAcceptPositionEvent read FOnDragAcceptPosition write FOnDragAcceptPosition;
- property OnDropFiles: TDropFilesEvent read FOnDropFiles write FOnDropFiles;
- end;
-
-
-function WindowsMimeLookup(const CFFormat: string): string;
-function WindowsClipboardLookup(const AMime: string; var IsTranslated: Boolean): DWORD;
-function EnumDataToStringList(DataObj: IDataObject): TStringList;
-function GetFormatEtc(const CFFormat: DWORD): FORMATETC;
-
-implementation
-
-uses
- SysUtils, ShlObj, fpg_widget;
-
-var
- CF_FILENAMEMAP: Cardinal;
- CF_FILEDESCRIPTOR: Cardinal;
- CF_FILECONTENTS: Cardinal;
-
-
-function WindowsMimeLookup(const CFFormat: string): string;
-begin
- { replace known clipboard formats with mime types }
- if CFFormat = 'CF_TEXT' then
- Result := 'text/plain'
- else if CFFormat = 'CF_UNICODETEXT' then
- Result := 'text/plain'
- else if CFFormat = 'CF_OEMTEXT' then
- Result := 'text/plain'
- else if CFFormat = 'CF_HDROP' then
- Result := 'text/uri-list'
- else if CFFormat = 'CF_RICHTEXT' then
- Result := 'text/html'
- else
- Result := CFFormat;
-end;
-
-function WindowsClipboardLookup(const AMime: string; var IsTranslated: Boolean): DWORD;
-begin
- { TODO: We need to improve this implementation }
- if AMime = 'text/html' then
- begin
- { We don't want duplicate CF_TEXT in DataObject, so register some of our
- known convenience types (from TfpgMimeData) as-is }
- IsTranslated := False;
- Result := RegisterClipboardFormat('text/html');
- end
- else if Pos('text/', AMime) = 1 then
- begin
- IsTranslated := True;
- Result := CF_TEXT; // fallback result
- end
- else
- begin
- IsTranslated := False;
- Result := RegisterClipboardFormat(PChar(AMime));
- end;
-end;
-
-function WindowsClipboardFormatToString(const CFFormat: integer): string;
-begin
- { replace know clipboard formats with mime types }
- case CFFormat of
- CF_DIF : result := 'CF_DIF';
- CF_DIB : result := 'CF_DIB';
- CF_TEXT : result := 'CF_TEXT';
- CF_SYLK : result := 'CF_SYLK';
- CF_TIFF : result := 'CF_TIFF';
- CF_RIFF : result := 'CF_RIFF';
- CF_WAVE : result := 'CF_WAVE';
- CF_HDROP : result := 'CF_HDROP';
- CF_BITMAP : result := 'CF_BITMAP';
- CF_LOCALE : result := 'CF_LOCALE';
- CF_OEMTEXT : result := 'CF_OEMTEXT';
- CF_PALETTE : result := 'CF_PALETTE';
- CF_PENDATA : result := 'CF_PENDATA';
- CF_UNICODETEXT : result := 'CF_UNICODETEXT';
- CF_ENHMETAFILE : result := 'CF_ENHMETAFILE';
- CF_METAFILEPICT : result := 'CF_METAFILEPICT';
- else
- Result := Format('unknown (%d)', [CFFormat]);
- end;
-end;
-
-function EnumDataToStringList(DataObj: IDataObject): TStringList;
-var
- FE: FORMATETC;
- EnumFormats: IEnumFORMATETC;
- num: integer;
- lname: string;
- lMimeName: string;
- FormatName: array[0..MAX_PATH] of Char;
- i: integer;
-begin
- if DataObj.EnumFormatEtc(DATADIR_GET, EnumFormats) <> S_OK then
- raise Exception.Create('EnumDataToStringList: Failed to get EnumFormatEtc interface');
-
- Result := TStringList.Create;
- EnumFormats.Reset;
- while EnumFormats.Next(1, FE, @num) = S_OK do
- begin
- lName := '';
- i := GetClipboardFormatName(FE.cfFormat,FormatName,MAX_PATH);
- if i <> 0 then
- begin
- lName := FormatName;
- end
- else
- begin
- lName := WindowsClipboardFormatToString(FE.cfFormat);
- end;
- Result.Add(lName);
- end;
-end;
-
-function GetFormatEtc(const CFFormat: DWORD): FORMATETC;
-begin
- Result.CfFormat := CFFormat;
- Result.Ptd := nil;
- Result.dwAspect := DVASPECT_CONTENT;
- Result.lindex := -1;
- Result.tymed := TYMED_HGLOBAL;
-end;
-
-procedure DeepCopyFormatEtc(P1, P2: PFormatEtc);
-begin
- P2^ := P1^;
- if P1^.ptd <> nil then begin
- P2^.ptd := CoTaskMemAlloc(SizeOf(tagDVTARGETDEVICE));
- P2^.ptd^ := P1^.ptd^;
- end;
-end;
-
-function DupGlobalMem(hMem: HGLOBAL): HGLOBAL;
-var
- len: DWORD;
- Source: Pointer;
- Dest: HGLOBAL;
-begin
- len := GlobalSize(hMem);
- Source := GlobalLock(hMem);
- Dest := GlobalAlloc(GMEM_FIXED, len);
- Move(Source^, Pointer(Dest)^, len);
- GlobalUnlock(hMem);
- Result := Dest;
-end;
-
-{ TDragFilesSource }
-
-constructor TDragFilesSource.Create;
-begin
- inherited Create;
- FFileNames := TStringList.Create;
- FAliasFileNames := TStringList.Create;
-end;
-
-destructor TDragFilesSource.Destroy;
-begin
- FreeAndNil(FFileNames);
- FreeAndNil(FAliasFileNames);
- inherited Destroy;
-end;
-
-procedure TDragFilesSource.Execute;
-var
- DataObject: TfpgOLEDataObject;
- DropSource: TfpgOLEDropSource;
- dwEffect: DWORD;
- dwResult: HRESULT;
- I: Integer;
- F: PFormatEtc;
- S: string;
- M: PStgMedium;
-begin
- DataObject := TfpgOLEDataObject.Create;
-
- { append filenames as one long string delimited by #0. ie: something like a PChar }
- S := '';
- for I := 0 to FFileNames.Count - 1 do
- begin
- SetLength(S, Length(S)+Length(FFileNames[I])+1);
- Move(FFileNames[I][1], S[Length(S)-Length(FFileNames[I])], Length(FFileNames[I]));
- S[Length(S)] := #0;
- end;
- SetLength(S, Length(S)+1);
- S[Length(S)] := #0;
-
- { description of data we are sending }
- New(F);
- F^.cfFormat := CF_HDROP;
- F^.ptd := nil;
- F^.dwAspect := DVASPECT_CONTENT;
- F^.lindex := -1;
- F^.tymed := TYMED_HGLOBAL;
- DataObject.FormatEtcList.Add(F);
-
- { storage for data we are sending }
- New(M);
- M^.tymed := TYMED_HGLOBAL;
- M^.hGlobal := Cardinal(GlobalAlloc(GMEM_FIXED, SizeOf(TDropFiles)+Length(S)));
- PDropFiles(M^.hGlobal)^.pFiles := SizeOf(TDropFiles);
- PDropFiles(M^.hGlobal)^.pt := Point(0,0);
- PDropFiles(M^.hGlobal)^.fNC := FALSE;
- PDropFiles(M^.hGlobal)^.fWide := FALSE;
- Move(S[1], PChar(M^.hGlobal+SizeOf(TDropFiles))^, Length(S));
- DataObject.StgMediumList.Add(M);
-
- if (FAliasFileNames.Count > 0) and (FAliasFileNames.Count = FFileNames.Count) then
- begin
- { append filename aliases as one long string delimited by #0. ie: something like a PChar }
- S := '';
- for I := 0 to FAliasFileNames.Count - 1 do
- begin
- SetLength(S, Length(S)+Length(FAliasFileNames[I])+1);
- Move(FAliasFileNames[I][1], S[Length(S)-Length(FAliasFileNames[I])], Length(FAliasFileNames[I]));
- S[Length(S)] := #0;
- end;
- SetLength(S, Length(S)+1);
- S[Length(S)] := #0;
-
- { description of data we are sending }
- New(F);
- F^.cfFormat := CF_FILENAMEMAP;
- F^.ptd := nil;
- F^.dwAspect := DVASPECT_CONTENT;
- F^.lindex := -1;
- F^.tymed := TYMED_HGLOBAL;
- DataObject.FormatEtcList.Add(F);
-
- { storage for data we are sending }
- New(M);
- M^.tymed := TYMED_HGLOBAL;
- M^.hGlobal := Cardinal(GlobalAlloc(GMEM_FIXED, Length(S)));
- Move(S[1], PChar(M^.hGlobal)^, Length(S));
- DataObject.StgMediumList.Add(M);
- end;
-
- DropSource := TfpgOLEDropSource.Create;
- dwResult := ActiveX.DoDragDrop(DataObject as IDataObject, DropSource as IDropSource, DROPEFFECT_COPY, @dwEffect);
-
- if dwResult = DRAGDROP_S_DROP then
- begin
- if dwEffect = DROPEFFECT_COPY then
- begin
- // nothing to do. If this whas xxx_MOVE, we would remove data from source
- end;
- end;
-end;
-
-function TDragFilesSource.GetAliasFileNames: TStrings;
-begin
- Result := FAliasFileNames;
-end;
-
-function TDragFilesSource.GetSourceFileNames: TStrings;
-begin
- Result := FFileNames;
-end;
-
-procedure TDragFilesSource.SetAliasFileNames(const Value: TStrings);
-begin
- FAliasFileNames.Assign(Value);
-end;
-
-procedure TDragFilesSource.SetSourceFileNames(const Value: TStrings);
-begin
- FFileNames.Assign(Value);
-end;
-
-{ TfpgOLEDropSource }
-
-{$IF FPC_FULLVERSION>=20601}
-function TfpgOLEDropSource.GiveFeedback(dwEffect: DWORD): HResult;
-{$ELSE}
-function TfpgOLEDropSource.GiveFeedback(dwEffect: longint): HResult;
-{$ENDIF}
-begin
- Result := DRAGDROP_S_USEDEFAULTCURSORS;
-end;
-
-{$IF FPC_FULLVERSION>=20601}
-function TfpgOLEDropSource.QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: DWORD):HResult;
-{$ELSE}
-function TfpgOLEDropSource.QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: LongInt): HResult;
-{$ENDIF}
-begin
- if FEscapePressed then
- Result := DRAGDROP_S_CANCEL
- else if (grfKeyState and (MK_LBUTTON or MK_RBUTTON) = 0) then
- Result := DRAGDROP_S_DROP
- else
- Result := S_OK;
- {$IFDEF DND_DEBUG}
- writeln('TfpgOLEDropSource.QueryContinueDrag Result = ', Result);
- {$ENDIF}
-end;
-
-{ TfpgOLEDataObject }
-
-constructor TfpgOLEDataObject.Create(AFormatEtcList: TfpgOLEFormatEtcList);
-begin
- inherited Create;
- FFormatEtcList := TfpgOLEFormatEtcList.CreateCopy(AFormatEtcList);
- FStgMediumList := TfpgOLEStgMediumList.Create;
-end;
-
-constructor TfpgOLEDataObject.Create;
-begin
- inherited Create;
- FFormatEtcList := TfpgOLEFormatEtcList.Create;
- FStgMediumList := TfpgOLEStgMediumList.Create;
-end;
-
-function TfpgOLEDataObject.DAdvise(const formatetc: TFormatEtc; advf: DWORD;
- const advSink: IAdviseSink; out dwConnection: DWORD): HResult;
-begin
- Result := OLE_E_ADVISENOTSUPPORTED;
-end;
-
-destructor TfpgOLEDataObject.Destroy;
-begin
- FreeAndNil(FFormatEtcList);
- FreeAndNil(FStgMediumList);
- inherited Destroy;
-end;
-
-function TfpgOLEDataObject.DUnadvise(dwConnection: DWORD): HResult;
-begin
- Result := OLE_E_ADVISENOTSUPPORTED;
-end;
-
-function TfpgOLEDataObject.EnumDAdvise(out enumAdvise: IEnumStatData): HResult;
-begin
- Result := OLE_E_ADVISENOTSUPPORTED;
-end;
-
-function TfpgOLEDataObject.EnumFormatEtc(dwDirection: DWORD;
- out enumFormatEtc: IEnumFormatEtc): HResult;
-begin
- if dwDirection = DATADIR_GET then
- begin
- enumFormatEtc := TfpgOLEEnumFormatEtc.Create(FFormatEtcList) as IEnumFormatEtc;
- Result := S_OK;
- end
- else begin
- Result := E_NOTIMPL;
- end;
-end;
-
-function TfpgOLEDataObject.GetCanonicalFormatEtc(const formatetc: TFormatEtc;
- out formatetcOut: TFormatEtc): HResult;
-begin
- // Apparently we have to set this field to NULL even though we don't do anything else
- formatetcOut.ptd := nil;
- Result := E_NOTIMPL;
-end;
-
-function TfpgOLEDataObject.GetData(const formatetcIn: TFormatEtc;
- out medium: TStgMedium): HResult;
-var
- Idx: Integer;
-begin
- Idx := LookupFormatEtc(formatetcIn);
- if Idx = -1 then
- Result := DV_E_FORMATETC
- else
- begin
- medium.tymed := FFormatEtcList[Idx]^.tymed;
- medium.PUnkForRelease := nil;
- if medium.tymed = TYMED_HGLOBAL then
- begin
- medium.hGlobal := DupGlobalMem(FStgMediumList[Idx]^.hGlobal);
- Result := S_OK;
- end
- else
- Result := DV_E_FORMATETC;
- end;
-end;
-
-function TfpgOLEDataObject.GetDataHere(const formatetc: TFormatEtc;
- out medium: TStgMedium): HResult;
-begin
- Result := DV_E_FORMATETC;
-end;
-
-function TfpgOLEDataObject.LookupFormatEtc(AFormat: TFormatEtc): Integer;
-var
- I: Integer;
-begin
- Result := -1;
- for I := 0 to FFormatEtcList.Count - 1 do begin
- if (FFormatEtcList[I]^.cfFormat = AFormat.cfFormat) and
- (FFormatEtcList[I]^.dwAspect = AFormat.dwAspect) and
- (FFormatEtcList[I]^.tymed = AFormat.tymed) then begin
- Result := I;
- Break;
- end;
- end;
-end;
-
-function TfpgOLEDataObject.QueryGetData(const formatetc: TFormatEtc): HResult;
-begin
- if LookupFormatEtc(formatetc) >= 0 then begin
- Result := S_OK;
- end
- else begin
- Result := DV_E_FORMATETC;
- end;
-end;
-
-function TfpgOLEDataObject.SetData(const formatetc: TFormatEtc;
- const medium: TStgMedium; fRelease: BOOL): HResult;
-begin
- Result := E_NOTIMPL;
-end;
-
-{ TfpgOLEEnumFormatEtc }
-
-function TfpgOLEEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
-var
- C: TfpgOLEEnumFormatEtc;
-begin
- // make a duplicate enumerator
- C := TfpgOLEEnumFormatEtc.Create(FFormatEtcList);
- // manually set the index state
- C.FIndex := FIndex;
- Enum := C as IEnumFormatEtc;
- Result := S_OK;
-end;
-
-constructor TfpgOLEEnumFormatEtc.Create(AFormatEtcList: TfpgOLEFormatEtcList);
-begin
- FFormatEtcList := TfpgOLEFormatEtcList.CreateCopy(AFormatEtcList);
- FIndex := 0;
-end;
-
-destructor TfpgOLEEnumFormatEtc.Destroy;
-begin
- FreeAndNil(FFormatEtcList);
- inherited;
-end;
-
-function TfpgOLEEnumFormatEtc.Next(celt: ULong; out elt:FormatEtc;
- pceltFetched: pULong): HResult;
-var
- Copied: Integer;
- OutBuf: PFormatEtc;
-begin
- // copy the FORMATETC structures into the caller's buffer
- OutBuf := PFormatEtc(@elt);
- Copied := 0;
- while(FIndex < FFormatEtcList.Count) and (Copied < celt) do begin
- DeepCopyFormatEtc(FFormatEtcList[FIndex], OutBuf);
- OutBuf := PFormatEtc(Cardinal(OutBuf) + SizeOf(TFormatEtc));
- Inc(Copied);
- FIndex := FIndex + 1;
- end;
-
- // store result
- if (pceltFetched <> nil) then
- pceltFetched^ := Copied;
-
- // did we copy all that was requested?
- if (Copied = celt) then Result := S_OK
- else Result := S_FALSE;
-end;
-
-function TfpgOLEEnumFormatEtc.Reset: HResult;
-begin
- FIndex := 0;
- Result := S_OK;
-end;
-
-function TfpgOLEEnumFormatEtc.Skip(celt: ULong): HResult;
-begin
- FIndex := FIndex + celt;
- if FIndex <= FFormatEtcList.Count then Result := S_OK
- else Result := S_FALSE;
-end;
-
-{ TfpgOLEFormatEtcList }
-
-constructor TfpgOLEFormatEtcList.CreateCopy(AFormatEtcList: TfpgOLEFormatEtcList);
-var
- I: Integer;
- P: PFormatEtc;
-begin
- Create;
- for I := 0 to AFormatEtcList.Count - 1 do begin
- New(P);
- DeepCopyFormatEtc(AFormatEtcList[I], P);
- Add(P);
- end;
-end;
-
-function TfpgOLEFormatEtcList.GetFormatEtc(Index: Integer): PFormatEtc;
-begin
- Result := PFormatEtc(Get(Index));
-end;
-
-procedure TfpgOLEFormatEtcList.Notify(Ptr: Pointer; Action: TListNotification);
-begin
- if Action = lnDeleted then begin
- if PFormatEtc(Ptr)^.ptd <> nil then begin
- CoTaskMemFree(PFormatEtc(Ptr)^.ptd);
- end;
- Dispose(PFormatEtc(Ptr));
- end;
- inherited;
-end;
-
-{ TfpgOLEStgMediumList }
-
-function TfpgOLEStgMediumList.GetStgMedium(Index: Integer): PStgMedium;
-begin
- Result := PStgMedium(Get(Index));
-end;
-
-procedure TfpgOLEStgMediumList.Notify(Ptr: Pointer; Action: TListNotification);
-begin
- if Action = lnDeleted then begin
- if PStgMedium(Ptr)^.hGlobal <> 0 then begin
- GlobalFree(PStgMedium(Ptr)^.hGlobal);
- end;
- Dispose(Ptr);
- end;
- inherited;
-end;
-
-{ TfpgOLEDropTarget }
-
-function TfpgOLEDropTarget.DragEnter(const dataObj: IDataObject;
- grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;
-//var
-// Effect: TfpgOLEDragDropEffect;
-begin
- //dwEffect := DROPEFFECT_NONE;
- //Effect := deNone;
- DoDragEnter(dataObj, grfKeyState, pt, dwEffect);
- //case Effect of
- // deNone: dwEffect := DROPEFFECT_NONE;
- // deCopy: dwEffect := DROPEFFECT_COPY;
- // deMove: dwEffect := DROPEFFECT_MOVE;
- // deLink: dwEffect := DROPEFFECT_LINK;
- //end;
- Result := S_OK;
-end;
-
-function TfpgOLEDropTarget.DragLeave: HResult;
-begin
- Result := S_OK;
- DoDragLeave;
-end;
-
-function TfpgOLEDropTarget.DragOver(grfKeyState: DWORD; pt: TPoint;
- var dwEffect: DWORD): HResult;
-var
- Effect: TfpgOLEDragDropEffect;
-begin
- if ((MK_SHIFT and grfKeyState) = MK_SHIFT) and
- ((dwEffect and DROPEFFECT_MOVE) = DROPEFFECT_MOVE) then begin
- Effect := deMove;
- end;
- if ((MK_CONTROL and grfKeyState) = MK_CONTROL) and
- ((dwEffect and DROPEFFECT_COPY) = DROPEFFECT_COPY) then begin
- Effect := deCopy;
- end;
- if dwEffect and DROPEFFECT_COPY > 0 then Effect := deCopy
- else if dwEffect and DROPEFFECT_MOVE > 0 then Effect := deMove
- else if dwEffect and DROPEFFECT_LINK > 0 then Effect := deLink
- else Effect := deNone;
- DoDragOver(grfKeyState, pt, Effect);
- case Effect of
- deNone: dwEffect := DROPEFFECT_NONE;
- deCopy: dwEffect := DROPEFFECT_COPY;
- deMove: dwEffect := DROPEFFECT_MOVE;
- deLink: dwEffect := DROPEFFECT_LINK;
- end;
- Result := S_OK;
-end;
-
-function TfpgOLEDropTarget.Drop(const dataObj: IDataObject;
- grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;
-var
- Effect: TfpgOLEDragDropEffect;
-begin
- if dwEffect and DROPEFFECT_COPY > 0 then
- Effect := deCopy
- else if dwEffect and DROPEFFECT_MOVE > 0 then
- Effect := deMove
- else if dwEffect and DROPEFFECT_LINK > 0 then
- Effect := deLink
- else
- Effect := deNone;
- DoDragDrop(dataObj, grfKeyState, pt, Effect);
- Result := S_OK;
-end;
-
-function TfpgOLEDropTarget._AddRef: longint;
-begin
- Result := 1;
-end;
-
-function TfpgOLEDropTarget._Release: longint;
-begin
- Result := 1;
-end;
-
-function TfpgOLEDropTarget.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: TGuid; out obj): longint; stdcall;
-begin
- if GetInterface(IID, Obj) then
- Result := 0
- else
- Result := E_NOINTERFACE;
-end;
-
-constructor TfpgOLEDropTarget.Create(ADropTargetWidget: TfpgWindowBase);
-begin
- inherited Create;
- FDropTarget := ADropTargetWidget;
- FRegistered := False;
-end;
-
-procedure TfpgOLEDropTarget.RegisterDragDrop;
-begin
- ActiveX.RegisterDragDrop(TfpgWidget(FDropTarget).WinHandle, Self as IDropTarget);
- FRegistered := True;
-end;
-
-procedure TfpgOLEDropTarget.RevokeDragDrop;
-begin
- FRegistered := False;
- ActiveX.RevokeDragDrop(TfpgWidget(FDropTarget).WinHandle);
-end;
-
-destructor TfpgOLEDropTarget.Destroy;
-begin
- if FRegistered then RevokeDragDrop;
- inherited;
-end;
-
-procedure TfpgOLEDropTarget.DoDragEnter(DataObj: IDataObject;
- KeyState: LongInt; PT: TPoint; var Effect: DWORD);
-begin
- if Assigned(FOnDragEnter) then begin
- FOnDragEnter(Self, DataObj, KeyState, PT, Effect);
- end;
-end;
-
-procedure TfpgOLEDropTarget.DoDragOver(KeyState: LongInt; PT: TPoint;
- var Effect: TfpgOLEDragDropEffect);
-begin
- if Assigned(FOnDragOver) then begin
- FOnDragOver(Self, KeyState, PT, Effect);
- end;
-end;
-
-procedure TfpgOLEDropTarget.DoDragLeave;
-begin
- if Assigned(FOnDragLeave) then
- FOnDragLeave(self);
-end;
-
-procedure TfpgOLEDropTarget.DoDragDrop(DataObj: IDataObject; KeyState: LongInt;
- PT: TPoint; Effect: TfpgOLEDragDropEffect);
-begin
- if Assigned(FOnDragDrop) then begin
- FOnDragDrop(Self, DataObj, KeyState, PT, Effect);
- end;
-end;
-
-{ TDragFilesTarget }
-
-function TDragFilesTarget.DoDragAcceptFiles(DataObj: IDataObject): Boolean;
-const
- FormatEtcHDrop: TFormatEtc = (cfFormat:CF_HDROP;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_HGLOBAL);
- FormatEtcFileDescriptor: TFormatEtc = (cfFormat:0;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_HGLOBAL);
- FormatEtcFileContents: TFormatEtc = (cfFormat:0;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_ISTREAM);
-var
- StgMedium: TStgMedium;
- DropHandle: HDROP;
- EnumFormatEtc: IEnumFORMATETC;
- FE: TFormatEtc;
- FetchedCount: Longint;
- FormatName: array[0..MAX_PATH] of Char;
- FileGroupDescriptor: PFileGroupDescriptorA;
- I, Count: Integer;
- FileDescriptor: TFileDescriptorA;
- FileNames: TStringList;
-begin
- FileNames := TStringList.Create;
- try
- if Assigned(FOnDragAcceptFiles) then
- begin
- Result := False;
- FormatEtcFileDescriptor.cfFormat := CF_FILEDESCRIPTOR;
- FormatEtcFileContents.cfFormat := CF_FILECONTENTS;
-
- if (DataObj.QueryGetData(FormatEtcHDrop) = S_OK) and
- (DataObj.GetData(FormatEtcHDrop,StgMedium) = S_OK) then
- begin
- DropHandle := StgMedium.hGlobal;
- GetFileNamesFromDropHandle(DropHandle, FileNames);
- Result := FOnDragAcceptFiles(Self, FileNames);
- ReleaseStgMedium(StgMedium);
- end
- else
- if (DataObj.QueryGetData(FormatEtcFileDescriptor) = S_OK) and
- (DataObj.QueryGetData(FormatEtcFileContents) = S_OK) and
- (DataObj.GetData(FormatEtcFileDescriptor,StgMedium) = S_OK) then
- begin
- FileGroupDescriptor := GlobalLock(StgMedium.hGlobal);
- if FileGroupDescriptor <> nil then
- begin
- Count := FileGroupDescriptor^.cItems;
- I := 0;
- while I < Count do
- begin
- FileDescriptor := FileGroupDescriptor^.fgd[I];
- FileNames.Add(FileDescriptor.cFileName);
- Inc(I);
- end;
- GlobalUnlock(StgMedium.hGlobal);
- end;
- Result := FOnDragAcceptFiles(Self, FileNames);
- ReleaseStgMedium(StgMedium);
- end
- else
- begin
-// DataObj.EnumFormatEtc(DATADIR_GET, EnumFormatEtc);
-// EnumFormatEtc.Reset;
-// while EnumFormatEtc.Next(1, FE, @FetchedCount) = S_OK do begin
-// GetClipboardFormatName(FE.cfFormat,FormatName,MAX_PATH);
-// ShowMessage(FormatName);
-// end;
- end;
- end
- else
- begin
- Result := True;
- end;
- finally
- FileNames.Free;
- end;
-end;
-
-procedure TDragFilesTarget.DoDragEnter(DataObj: IDataObject;
- KeyState: LongInt; PT: TPoint; var Effect: DWORD);
-begin
- FDragAcceptFiles := DoDragAcceptFiles(DataObj);
- if FDragAcceptFiles and DoDragAcceptPosition(PT) then
- inherited DoDragEnter(DataObj, KeyState, PT, Effect)
- else
- Effect := DROPEFFECT_NONE;
-end;
-
-procedure TDragFilesTarget.DoDragOver(KeyState: LongInt; PT: TPoint; var Effect: TfpgOLEDragDropEffect);
-begin
- if FDragAcceptFiles and DoDragAcceptPosition(PT) then
- inherited DoDragOver(KeyState, PT, Effect)
- else
- Effect := deNone;
-end;
-
-procedure TDragFilesTarget.DoDragDrop(DataObj: IDataObject;
- KeyState: LongInt; PT: TPoint; Effect: TfpgOLEDragDropEffect);
-begin
- DoDropFiles(DataObj, PT);
- inherited;
-end;
-
-function TDragFilesTarget.DoDragAcceptPosition(PT: TPoint): Boolean;
-begin
- if Assigned(FOnDragAcceptPosition) then begin
- Result := FOnDragAcceptPosition(Self, PT);
- end else begin
- Result := True;
- end;
-end;
-
-procedure TDragFilesTarget.DoDropFiles(DataObj: IDataObject; PT: TPoint);
-const
- FormatEtcHDrop: TFormatEtc = (cfFormat:CF_HDROP;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_HGLOBAL);
- FormatEtcFileDescriptor: TFormatEtc =
- (cfFormat:0;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_HGLOBAL);
- FormatEtcFileContents: TFormatEtc =
- (cfFormat:0;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_ISTREAM);
-var
- StgMedium, StgMediumContents: TStgMedium;
- DropHandle: HDROP;
- FileNames: TStringList;
- FileGroupDescriptor: PFileGroupDescriptorA;
- I, Count: Integer;
- FileDescriptor: TFileDescriptorA;
- Path: array[0..MAX_PATH] of Char;
- TempFileName: string;
-begin
- if not Assigned(FOnDropFiles) then Exit;
- FileNames := TStringList.Create;
- try
- FormatEtcFileDescriptor.cfFormat := CF_FILEDESCRIPTOR;
- FormatEtcFileContents.cfFormat := CF_FILECONTENTS;
- if (DataObj.QueryGetData(FormatEtcHDrop) = S_OK) and
- (DataObj.GetData(FormatEtcHDrop,StgMedium) = S_OK) then begin
- DropHandle := StgMedium.hGlobal;
- GetFileNamesFromDropHandle(DropHandle, FileNames);
- FOnDropFiles(Self, PT, FileNames);
- ReleaseStgMedium(StgMedium);
- end else
- if (DataObj.QueryGetData(FormatEtcFileDescriptor) = S_OK) and
- (DataObj.QueryGetData(FormatEtcFileContents) = S_OK) and
- (DataObj.GetData(FormatEtcFileDescriptor,StgMedium) = S_OK) then begin
- GetTempPath(MAX_PATH, Path);
- GetTempFileName(Path, 'PXM', 0, Path);
- FileGroupDescriptor := GlobalLock(StgMedium.hGlobal);
- if FileGroupDescriptor <> nil then begin
- Count := FileGroupDescriptor^.cItems;
- I := 0;
- while I < Count do begin
- FileDescriptor := FileGroupDescriptor^.fgd[I];
- TempFileName := ChangeFileExt(Path, ExtractFileExt(FileDescriptor.cFileName));
- FormatEtcFileContents.lindex := I;
- if (DataObj.GetData(FormatEtcFileContents,StgMediumContents) = S_OK) then begin
- StreamToFile(IStream(StgMediumContents.pstm), TempFileName);
- FileNames.Clear;
- FileNames.Add(TempFileName);
- FOnDropFiles(Self, PT, FileNames);
- ReleaseStgMedium(StgMediumContents);
- end;
- Inc(I);
- end;
- GlobalUnlock(StgMedium.hGlobal);
- end;
- FOnDropFiles(Self, PT, FileNames);
- ReleaseStgMedium(StgMedium);
- ReleaseStgMedium(StgMediumContents);
- end;
- finally
- FileNames.Free;
- end;
-end;
-
-procedure TDragFilesTarget.GetFileNamesFromDropHandle(DropHandle: HDROP; SL: TStrings);
-var
- I: Integer;
- Path: array[0..MAX_PATH] of Char;
-begin
- for I := 0 to DragQueryFile(DropHandle, $FFFFFFFF, nil, 0) do begin
- DragQueryFile(DropHandle, I, Path, MAX_PATH);
- SL.Add(Path);
- end;
- DragFinish(DropHandle);
-end;
-
-procedure TDragFilesTarget.StreamToFile(Stream: IStream; const FileName: string);
-const
- BLOCK_SIZE = 4096;
-var
- BytesRead: Longint;
- FileStream: TFileStream;
- Buffer: array[0..BLOCK_SIZE] of Byte;
-begin
- FileStream := TFileStream.Create(FileName, fmCreate);
- try
- while (Stream.Read(@Buffer[0], BLOCK_SIZE, @BytesRead) = S_OK) and (BytesRead > 0) do begin
- FileStream.Write(Buffer, BytesRead);
- end;
- finally
- FileStream.Free;
- end;
-end;
-
-initialization
- CF_FILENAMEMAP := RegisterClipboardFormat(CFSTR_FILENAMEMAP);
- CF_FILEDESCRIPTOR := RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
- CF_FILECONTENTS := RegisterClipboardFormat(CFSTR_FILECONTENTS);
-
-finalization
-
-end.
-
+{ + fpGUI - Free Pascal GUI Toolkit + + Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + distribution, for details of the copyright. + + See the file COPYING.modifiedLGPL, included in this distribution, + for details about redistributing fpGUI. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + This unit implements the OLE Drag-n-Drop functionality of Windows. + This unit is implemented based on the articles posted on + http://www.catch22.net/tuts/dragdrop/ +} +unit fpg_OLEDragDrop; + +{$mode delphi}{$H+} + +interface + +uses + Windows, Classes, ActiveX, ShellAPI, fpg_base; + +const + CFSTR_FILENAMEMAPA = 'FileNameMap'; { CF_FILENAMEMAPA } + CFSTR_FILENAMEMAP = CFSTR_FILENAMEMAPA; + CFSTR_FILEDESCRIPTORA = 'FileGroupDescriptor'; { CF_FILEGROUPDESCRIPTORA } + CFSTR_FILEDESCRIPTOR = CFSTR_FILEDESCRIPTORA; + CFSTR_FILECONTENTS = 'FileContents'; { CF_FILECONTENTS } + +type + TfpgOLEFormatEtcList = class(TList) + private + function GetFormatEtc(Index: Integer): PFormatEtc; + protected + procedure Notify(Ptr: Pointer; Action: TListNotification); override; + public + constructor CreateCopy(AFormatEtcList: TfpgOLEFormatEtcList); + property FormatEtc[Index: Integer]: PFormatEtc read GetFormatEtc; default; + end; + + + TfpgOLEStgMediumList = class(TList) + private + function GetStgMedium(Index: Integer): PStgMedium; + protected + procedure Notify(Ptr: Pointer; Action: TListNotification); override; + public + property StgMedium[Index: Integer]: PStgMedium read GetStgMedium; default; + end; + + + TfpgOLEDropSource = class(TInterfacedObject, IDropSource) + private + { IDropSource } + {$IF FPC_FULLVERSION>=20601} + function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: DWORD):HResult; StdCall; + function GiveFeedback(dwEffect: DWORD): HResult; StdCall; + {$ELSE} + function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: Longint): HResult; stdcall; + function GiveFeedback(dwEffect: longint): HResult; stdcall; + {$ENDIF} + end; + + + TfpgOLEDragDropEffect = (deNone, deCopy, deMove, deLink); + TfpgOLEDragEnterEvent = procedure(Sender: TObject; DataObj: IDataObject; KeyState: Longint; PT: TPoint; var Effect: DWORD) of object; + TfpgOLEDragOverEvent = procedure(Sender: TObject; KeyState: Longint; PT: TPoint; var Effect: TfpgOLEDragDropEffect) of object; + TfpgOLEDragDropEvent = procedure(Sender: TObject; DataObj: IDataObject; KeyState: Longint; PT: TPoint; Effect: TfpgOLEDragDropEffect) of object; + + + TfpgOLEDropTarget = class(TObject, IInterface, IDropTarget) + private + FDropTarget: TfpgWindowBase; + FRegistered: Boolean; + FOnDragEnter: TfpgOLEDragEnterEvent; + FOnDragOver: TfpgOLEDragOverEvent; + FOnDragLeave: TNotifyEvent; + FOnDragDrop: TfpgOLEDragDropEvent; + private + { IInterface } + function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: TGuid; out obj): LongInt; stdcall; + function _AddRef: longint; stdcall; + function _Release: longint; stdcall; + { IDropTarget } + function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall; + function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult; stdcall; + function DragLeave: HResult; stdcall; + function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult; stdcall; + protected + procedure DoDragEnter(DataObj: IDataObject; KeyState: Longint; PT: TPoint; var Effect: DWORD); virtual; + procedure DoDragOver(KeyState: Longint; PT: TPoint; var Effect: TfpgOLEDragDropEffect); virtual; + procedure DoDragLeave; + procedure DoDragDrop(DataObj: IDataObject; KeyState: Longint; PT: TPoint; Effect: TfpgOLEDragDropEffect); virtual; + public + property OnDragEnter: TfpgOLEDragEnterEvent read FOnDragEnter write FOnDragEnter; + property OnDragOver: TfpgOLEDragOverEvent read FOnDragOver write FOnDragOver; + property OnDragLeave: TNotifyEvent read FOnDragLeave write FOnDragLeave; + property OnDragDrop: TfpgOLEDragDropEvent read FOnDragDrop write FOnDragDrop; + public + constructor Create(ADropTargetWidget: TfpgWindowBase); reintroduce; { Actually a TfpgWidget } + destructor Destroy; override; + procedure RegisterDragDrop; + procedure RevokeDragDrop; + property DropTarget: TfpgWindowBase read FDropTarget; + end; + + + TfpgOLEDataObject = class(TInterfacedObject, IDataObject) + private + FFormatEtcList: TfpgOLEFormatEtcList; + FStgMediumList: TfpgOLEStgMediumList; + function LookupFormatEtc(AFormat: TFormatEtc): Integer; + protected + { IDataObject } + function GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult; stdcall; + function GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium): HResult; stdcall; + function QueryGetData(const formatetc: TFormatEtc): HResult; stdcall; + function GetCanonicalFormatEtc(const formatetc: TFormatEtc; out formatetcOut: TFormatEtc): HResult; stdcall; + function SetData(const formatetc: TFormatEtc; const medium: TStgMedium; fRelease: BOOL): HResult; stdcall; + function EnumFormatEtc(dwDirection: DWORD; out enumFormatEtc: IEnumFormatEtc): HResult; stdcall; + function DAdvise(const formatetc: TFormatEtc; advf: DWORD; const advSink: IAdviseSink; out dwConnection: DWORD): HResult; stdcall; + function DUnadvise(dwConnection: DWORD): HResult; stdcall; + function EnumDAdvise(out enumAdvise: IEnumStatData): HResult; stdcall; + public + constructor Create; overload; + constructor Create(AFormatEtcList: TfpgOLEFormatEtcList); overload; + destructor Destroy; override; + property FormatEtcList: TfpgOLEFormatEtcList read FFormatEtcList; + property StgMediumList: TfpgOLEStgMediumList read FStgMediumList; + end; + + + TfpgOLEEnumFormatEtc = class(TInterfacedObject, IEnumFORMATETC) + private + FFormatEtcList: TfpgOLEFormatEtcList; + FIndex: Integer; + protected + { IEnumFORMATETC } + function Next(celt: ULong; out elt:FormatEtc; pceltFetched: pULong=nil): HResult; stdcall; + function Skip(celt: ULong): HResult; stdcall; + function Reset: HResult; stdcall; + function Clone(out Enum: IEnumFormatEtc): HResult; stdcall; + public + constructor Create(AFormatEtcList: TfpgOLEFormatEtcList); + destructor Destroy; override; + end; + + + TDragFilesSource = class(TObject) + private + FFileNames: TStrings; + FAliasFileNames: TStrings; + function GetAliasFileNames: TStrings; + function GetSourceFileNames: TStrings; + procedure SetAliasFileNames(const Value: TStrings); + procedure SetSourceFileNames(const Value: TStrings); + public + constructor Create; + destructor Destroy; override; + procedure Execute; + property SourceFileNames: TStrings read GetSourceFileNames write SetSourceFileNames; + property AliasFileNames: TStrings read GetAliasFileNames write SetAliasFileNames; + end; + + + TDragAcceptFilesEvent = function(Sender: TObject; FileNames: TStrings): Boolean of object; + TDragAcceptPositionEvent = function(Sender: TObject; PT: TPoint): Boolean of object; + TDropFilesEvent = procedure(Sender: TObject; PT: TPoint; FileNames: TStrings) of object; + + + TDragFilesTarget = class(TfpgOLEDropTarget) + private + FDragAcceptFiles: Boolean; + FOnDragAcceptFiles: TDragAcceptFilesEvent; + FOnDragAcceptPosition: TDragAcceptPositionEvent; + FOnDropFiles: TDropFilesEvent; + procedure GetFileNamesFromDropHandle(DropHandle: HDROP; SL: TStrings); + procedure StreamToFile(Stream: IStream; const FileName: string); + protected + function DoDragAcceptFiles(DataObj: IDataObject): Boolean; + function DoDragAcceptPosition(PT: TPoint): Boolean; + procedure DoDropFiles(DataObj: IDataObject; PT: TPoint); + procedure DoDragEnter(DataObj: IDataObject; KeyState: Longint; PT: TPoint; var Effect: DWORD); override; + procedure DoDragOver(KeyState: Longint; PT: TPoint; var Effect: TfpgOLEDragDropEffect); override; + procedure DoDragDrop(DataObj: IDataObject; KeyState: Longint; PT: TPoint; Effect: TfpgOLEDragDropEffect); override; + public + property OnDragAcceptFiles: TDragAcceptFilesEvent read FOnDragAcceptFiles write FOnDragAcceptFiles; + property OnDragAcceptPosition: TDragAcceptPositionEvent read FOnDragAcceptPosition write FOnDragAcceptPosition; + property OnDropFiles: TDropFilesEvent read FOnDropFiles write FOnDropFiles; + end; + + +function WindowsMimeLookup(const CFFormat: string): string; +function WindowsClipboardLookup(const AMime: string; var IsTranslated: Boolean): DWORD; +function EnumDataToStringList(DataObj: IDataObject): TStringList; +function GetFormatEtc(const CFFormat: DWORD): FORMATETC; + +implementation + +uses + SysUtils, ShlObj, fpg_widget; + +var + CF_FILENAMEMAP: Cardinal; + CF_FILEDESCRIPTOR: Cardinal; + CF_FILECONTENTS: Cardinal; + + +function WindowsMimeLookup(const CFFormat: string): string; +begin + { replace known clipboard formats with mime types } + if CFFormat = 'CF_TEXT' then + Result := 'text/plain' + else if CFFormat = 'CF_UNICODETEXT' then + Result := 'text/plain' + else if CFFormat = 'CF_OEMTEXT' then + Result := 'text/plain' + else if CFFormat = 'CF_HDROP' then + Result := 'text/uri-list' + else if CFFormat = 'CF_RICHTEXT' then + Result := 'text/html' + else + Result := CFFormat; +end; + +function WindowsClipboardLookup(const AMime: string; var IsTranslated: Boolean): DWORD; +begin + { TODO: We need to improve this implementation } + if AMime = 'text/html' then + begin + { We don't want duplicate CF_TEXT in DataObject, so register some of our + known convenience types (from TfpgMimeData) as-is } + IsTranslated := False; + Result := RegisterClipboardFormat('text/html'); + end + else if Pos('text/', AMime) = 1 then + begin + IsTranslated := True; + Result := CF_TEXT; // fallback result + end + else + begin + IsTranslated := False; + Result := RegisterClipboardFormat(PChar(AMime)); + end; +end; + +function WindowsClipboardFormatToString(const CFFormat: integer): string; +begin + { replace know clipboard formats with mime types } + case CFFormat of + CF_DIF : result := 'CF_DIF'; + CF_DIB : result := 'CF_DIB'; + CF_TEXT : result := 'CF_TEXT'; + CF_SYLK : result := 'CF_SYLK'; + CF_TIFF : result := 'CF_TIFF'; + CF_RIFF : result := 'CF_RIFF'; + CF_WAVE : result := 'CF_WAVE'; + CF_HDROP : result := 'CF_HDROP'; + CF_BITMAP : result := 'CF_BITMAP'; + CF_LOCALE : result := 'CF_LOCALE'; + CF_OEMTEXT : result := 'CF_OEMTEXT'; + CF_PALETTE : result := 'CF_PALETTE'; + CF_PENDATA : result := 'CF_PENDATA'; + CF_UNICODETEXT : result := 'CF_UNICODETEXT'; + CF_ENHMETAFILE : result := 'CF_ENHMETAFILE'; + CF_METAFILEPICT : result := 'CF_METAFILEPICT'; + else + Result := Format('unknown (%d)', [CFFormat]); + end; +end; + +function EnumDataToStringList(DataObj: IDataObject): TStringList; +var + FE: FORMATETC; + EnumFormats: IEnumFORMATETC; + num: integer; + lname: string; + lMimeName: string; + FormatName: array[0..MAX_PATH] of Char; + i: integer; +begin + if DataObj.EnumFormatEtc(DATADIR_GET, EnumFormats) <> S_OK then + raise Exception.Create('EnumDataToStringList: Failed to get EnumFormatEtc interface'); + + Result := TStringList.Create; + EnumFormats.Reset; + while EnumFormats.Next(1, FE, @num) = S_OK do + begin + lName := ''; + i := GetClipboardFormatName(FE.cfFormat,FormatName,MAX_PATH); + if i <> 0 then + begin + lName := FormatName; + end + else + begin + lName := WindowsClipboardFormatToString(FE.cfFormat); + end; + Result.Add(lName); + end; +end; + +function GetFormatEtc(const CFFormat: DWORD): FORMATETC; +begin + Result.CfFormat := CFFormat; + Result.Ptd := nil; + Result.dwAspect := DVASPECT_CONTENT; + Result.lindex := -1; + Result.tymed := TYMED_HGLOBAL; +end; + +procedure DeepCopyFormatEtc(P1, P2: PFormatEtc); +begin + P2^ := P1^; + if P1^.ptd <> nil then begin + P2^.ptd := CoTaskMemAlloc(SizeOf(tagDVTARGETDEVICE)); + P2^.ptd^ := P1^.ptd^; + end; +end; + +function DupGlobalMem(hMem: HGLOBAL): HGLOBAL; +var + len: DWORD; + Source: Pointer; + Dest: HGLOBAL; +begin + len := GlobalSize(hMem); + Source := GlobalLock(hMem); + Dest := GlobalAlloc(GMEM_FIXED, len); + Move(Source^, Pointer(Dest)^, len); + GlobalUnlock(hMem); + Result := Dest; +end; + +{ TDragFilesSource } + +constructor TDragFilesSource.Create; +begin + inherited Create; + FFileNames := TStringList.Create; + FAliasFileNames := TStringList.Create; +end; + +destructor TDragFilesSource.Destroy; +begin + FreeAndNil(FFileNames); + FreeAndNil(FAliasFileNames); + inherited Destroy; +end; + +procedure TDragFilesSource.Execute; +var + DataObject: TfpgOLEDataObject; + DropSource: TfpgOLEDropSource; + dwEffect: DWORD; + dwResult: HRESULT; + I: Integer; + F: PFormatEtc; + S: string; + M: PStgMedium; +begin + DataObject := TfpgOLEDataObject.Create; + + { append filenames as one long string delimited by #0. ie: something like a PChar } + S := ''; + for I := 0 to FFileNames.Count - 1 do + begin + SetLength(S, Length(S)+Length(FFileNames[I])+1); + Move(FFileNames[I][1], S[Length(S)-Length(FFileNames[I])], Length(FFileNames[I])); + S[Length(S)] := #0; + end; + SetLength(S, Length(S)+1); + S[Length(S)] := #0; + + { description of data we are sending } + New(F); + F^.cfFormat := CF_HDROP; + F^.ptd := nil; + F^.dwAspect := DVASPECT_CONTENT; + F^.lindex := -1; + F^.tymed := TYMED_HGLOBAL; + DataObject.FormatEtcList.Add(F); + + { storage for data we are sending } + New(M); + M^.tymed := TYMED_HGLOBAL; + M^.hGlobal := Cardinal(GlobalAlloc(GMEM_FIXED, SizeOf(TDropFiles)+Length(S))); + PDropFiles(M^.hGlobal)^.pFiles := SizeOf(TDropFiles); + PDropFiles(M^.hGlobal)^.pt := Point(0,0); + PDropFiles(M^.hGlobal)^.fNC := FALSE; + PDropFiles(M^.hGlobal)^.fWide := FALSE; + Move(S[1], PChar(M^.hGlobal+SizeOf(TDropFiles))^, Length(S)); + DataObject.StgMediumList.Add(M); + + if (FAliasFileNames.Count > 0) and (FAliasFileNames.Count = FFileNames.Count) then + begin + { append filename aliases as one long string delimited by #0. ie: something like a PChar } + S := ''; + for I := 0 to FAliasFileNames.Count - 1 do + begin + SetLength(S, Length(S)+Length(FAliasFileNames[I])+1); + Move(FAliasFileNames[I][1], S[Length(S)-Length(FAliasFileNames[I])], Length(FAliasFileNames[I])); + S[Length(S)] := #0; + end; + SetLength(S, Length(S)+1); + S[Length(S)] := #0; + + { description of data we are sending } + New(F); + F^.cfFormat := CF_FILENAMEMAP; + F^.ptd := nil; + F^.dwAspect := DVASPECT_CONTENT; + F^.lindex := -1; + F^.tymed := TYMED_HGLOBAL; + DataObject.FormatEtcList.Add(F); + + { storage for data we are sending } + New(M); + M^.tymed := TYMED_HGLOBAL; + M^.hGlobal := Cardinal(GlobalAlloc(GMEM_FIXED, Length(S))); + Move(S[1], PChar(M^.hGlobal)^, Length(S)); + DataObject.StgMediumList.Add(M); + end; + + DropSource := TfpgOLEDropSource.Create; + dwResult := ActiveX.DoDragDrop(DataObject as IDataObject, DropSource as IDropSource, DROPEFFECT_COPY, @dwEffect); + + if dwResult = DRAGDROP_S_DROP then + begin + if dwEffect = DROPEFFECT_COPY then + begin + // nothing to do. If this whas xxx_MOVE, we would remove data from source + end; + end; +end; + +function TDragFilesSource.GetAliasFileNames: TStrings; +begin + Result := FAliasFileNames; +end; + +function TDragFilesSource.GetSourceFileNames: TStrings; +begin + Result := FFileNames; +end; + +procedure TDragFilesSource.SetAliasFileNames(const Value: TStrings); +begin + FAliasFileNames.Assign(Value); +end; + +procedure TDragFilesSource.SetSourceFileNames(const Value: TStrings); +begin + FFileNames.Assign(Value); +end; + +{ TfpgOLEDropSource } + +{$IF FPC_FULLVERSION>=20601} +function TfpgOLEDropSource.GiveFeedback(dwEffect: DWORD): HResult; +{$ELSE} +function TfpgOLEDropSource.GiveFeedback(dwEffect: longint): HResult; +{$ENDIF} +begin + Result := DRAGDROP_S_USEDEFAULTCURSORS; +end; + +{$IF FPC_FULLVERSION>=20601} +function TfpgOLEDropSource.QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: DWORD):HResult; +{$ELSE} +function TfpgOLEDropSource.QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: LongInt): HResult; +{$ENDIF} +begin + if FEscapePressed then + Result := DRAGDROP_S_CANCEL + else if (grfKeyState and (MK_LBUTTON or MK_RBUTTON) = 0) then + Result := DRAGDROP_S_DROP + else + Result := S_OK; + {$IFDEF DND_DEBUG} + writeln('TfpgOLEDropSource.QueryContinueDrag Result = ', Result); + {$ENDIF} +end; + +{ TfpgOLEDataObject } + +constructor TfpgOLEDataObject.Create(AFormatEtcList: TfpgOLEFormatEtcList); +begin + inherited Create; + FFormatEtcList := TfpgOLEFormatEtcList.CreateCopy(AFormatEtcList); + FStgMediumList := TfpgOLEStgMediumList.Create; +end; + +constructor TfpgOLEDataObject.Create; +begin + inherited Create; + FFormatEtcList := TfpgOLEFormatEtcList.Create; + FStgMediumList := TfpgOLEStgMediumList.Create; +end; + +function TfpgOLEDataObject.DAdvise(const formatetc: TFormatEtc; advf: DWORD; + const advSink: IAdviseSink; out dwConnection: DWORD): HResult; +begin + Result := OLE_E_ADVISENOTSUPPORTED; +end; + +destructor TfpgOLEDataObject.Destroy; +begin + FreeAndNil(FFormatEtcList); + FreeAndNil(FStgMediumList); + inherited Destroy; +end; + +function TfpgOLEDataObject.DUnadvise(dwConnection: DWORD): HResult; +begin + Result := OLE_E_ADVISENOTSUPPORTED; +end; + +function TfpgOLEDataObject.EnumDAdvise(out enumAdvise: IEnumStatData): HResult; +begin + Result := OLE_E_ADVISENOTSUPPORTED; +end; + +function TfpgOLEDataObject.EnumFormatEtc(dwDirection: DWORD; + out enumFormatEtc: IEnumFormatEtc): HResult; +begin + if dwDirection = DATADIR_GET then + begin + enumFormatEtc := TfpgOLEEnumFormatEtc.Create(FFormatEtcList) as IEnumFormatEtc; + Result := S_OK; + end + else begin + Result := E_NOTIMPL; + end; +end; + +function TfpgOLEDataObject.GetCanonicalFormatEtc(const formatetc: TFormatEtc; + out formatetcOut: TFormatEtc): HResult; +begin + // Apparently we have to set this field to NULL even though we don't do anything else + formatetcOut.ptd := nil; + Result := E_NOTIMPL; +end; + +function TfpgOLEDataObject.GetData(const formatetcIn: TFormatEtc; + out medium: TStgMedium): HResult; +var + Idx: Integer; +begin + Idx := LookupFormatEtc(formatetcIn); + if Idx = -1 then + Result := DV_E_FORMATETC + else + begin + medium.tymed := FFormatEtcList[Idx]^.tymed; + medium.PUnkForRelease := nil; + if medium.tymed = TYMED_HGLOBAL then + begin + medium.hGlobal := DupGlobalMem(FStgMediumList[Idx]^.hGlobal); + Result := S_OK; + end + else + Result := DV_E_FORMATETC; + end; +end; + +function TfpgOLEDataObject.GetDataHere(const formatetc: TFormatEtc; + out medium: TStgMedium): HResult; +begin + Result := DV_E_FORMATETC; +end; + +function TfpgOLEDataObject.LookupFormatEtc(AFormat: TFormatEtc): Integer; +var + I: Integer; +begin + Result := -1; + for I := 0 to FFormatEtcList.Count - 1 do begin + if (FFormatEtcList[I]^.cfFormat = AFormat.cfFormat) and + (FFormatEtcList[I]^.dwAspect = AFormat.dwAspect) and + (FFormatEtcList[I]^.tymed = AFormat.tymed) then begin + Result := I; + Break; + end; + end; +end; + +function TfpgOLEDataObject.QueryGetData(const formatetc: TFormatEtc): HResult; +begin + if LookupFormatEtc(formatetc) >= 0 then begin + Result := S_OK; + end + else begin + Result := DV_E_FORMATETC; + end; +end; + +function TfpgOLEDataObject.SetData(const formatetc: TFormatEtc; + const medium: TStgMedium; fRelease: BOOL): HResult; +begin + Result := E_NOTIMPL; +end; + +{ TfpgOLEEnumFormatEtc } + +function TfpgOLEEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult; +var + C: TfpgOLEEnumFormatEtc; +begin + // make a duplicate enumerator + C := TfpgOLEEnumFormatEtc.Create(FFormatEtcList); + // manually set the index state + C.FIndex := FIndex; + Enum := C as IEnumFormatEtc; + Result := S_OK; +end; + +constructor TfpgOLEEnumFormatEtc.Create(AFormatEtcList: TfpgOLEFormatEtcList); +begin + FFormatEtcList := TfpgOLEFormatEtcList.CreateCopy(AFormatEtcList); + FIndex := 0; +end; + +destructor TfpgOLEEnumFormatEtc.Destroy; +begin + FreeAndNil(FFormatEtcList); + inherited; +end; + +function TfpgOLEEnumFormatEtc.Next(celt: ULong; out elt:FormatEtc; + pceltFetched: pULong): HResult; +var + Copied: Integer; + OutBuf: PFormatEtc; +begin + // copy the FORMATETC structures into the caller's buffer + OutBuf := PFormatEtc(@elt); + Copied := 0; + while(FIndex < FFormatEtcList.Count) and (Copied < celt) do begin + DeepCopyFormatEtc(FFormatEtcList[FIndex], OutBuf); + OutBuf := PFormatEtc(Cardinal(OutBuf) + SizeOf(TFormatEtc)); + Inc(Copied); + FIndex := FIndex + 1; + end; + + // store result + if (pceltFetched <> nil) then + pceltFetched^ := Copied; + + // did we copy all that was requested? + if (Copied = celt) then Result := S_OK + else Result := S_FALSE; +end; + +function TfpgOLEEnumFormatEtc.Reset: HResult; +begin + FIndex := 0; + Result := S_OK; +end; + +function TfpgOLEEnumFormatEtc.Skip(celt: ULong): HResult; +begin + FIndex := FIndex + celt; + if FIndex <= FFormatEtcList.Count then Result := S_OK + else Result := S_FALSE; +end; + +{ TfpgOLEFormatEtcList } + +constructor TfpgOLEFormatEtcList.CreateCopy(AFormatEtcList: TfpgOLEFormatEtcList); +var + I: Integer; + P: PFormatEtc; +begin + Create; + for I := 0 to AFormatEtcList.Count - 1 do begin + New(P); + DeepCopyFormatEtc(AFormatEtcList[I], P); + Add(P); + end; +end; + +function TfpgOLEFormatEtcList.GetFormatEtc(Index: Integer): PFormatEtc; +begin + Result := PFormatEtc(Get(Index)); +end; + +procedure TfpgOLEFormatEtcList.Notify(Ptr: Pointer; Action: TListNotification); +begin + if Action = lnDeleted then begin + if PFormatEtc(Ptr)^.ptd <> nil then begin + CoTaskMemFree(PFormatEtc(Ptr)^.ptd); + end; + Dispose(PFormatEtc(Ptr)); + end; + inherited; +end; + +{ TfpgOLEStgMediumList } + +function TfpgOLEStgMediumList.GetStgMedium(Index: Integer): PStgMedium; +begin + Result := PStgMedium(Get(Index)); +end; + +procedure TfpgOLEStgMediumList.Notify(Ptr: Pointer; Action: TListNotification); +begin + if Action = lnDeleted then begin + if PStgMedium(Ptr)^.hGlobal <> 0 then begin + GlobalFree(PStgMedium(Ptr)^.hGlobal); + end; + Dispose(Ptr); + end; + inherited; +end; + +{ TfpgOLEDropTarget } + +function TfpgOLEDropTarget.DragEnter(const dataObj: IDataObject; + grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult; +//var +// Effect: TfpgOLEDragDropEffect; +begin + //dwEffect := DROPEFFECT_NONE; + //Effect := deNone; + DoDragEnter(dataObj, grfKeyState, pt, dwEffect); + //case Effect of + // deNone: dwEffect := DROPEFFECT_NONE; + // deCopy: dwEffect := DROPEFFECT_COPY; + // deMove: dwEffect := DROPEFFECT_MOVE; + // deLink: dwEffect := DROPEFFECT_LINK; + //end; + Result := S_OK; +end; + +function TfpgOLEDropTarget.DragLeave: HResult; +begin + Result := S_OK; + DoDragLeave; +end; + +function TfpgOLEDropTarget.DragOver(grfKeyState: DWORD; pt: TPoint; + var dwEffect: DWORD): HResult; +var + Effect: TfpgOLEDragDropEffect; +begin + if ((MK_SHIFT and grfKeyState) = MK_SHIFT) and + ((dwEffect and DROPEFFECT_MOVE) = DROPEFFECT_MOVE) then begin + Effect := deMove; + end; + if ((MK_CONTROL and grfKeyState) = MK_CONTROL) and + ((dwEffect and DROPEFFECT_COPY) = DROPEFFECT_COPY) then begin + Effect := deCopy; + end; + if dwEffect and DROPEFFECT_COPY > 0 then Effect := deCopy + else if dwEffect and DROPEFFECT_MOVE > 0 then Effect := deMove + else if dwEffect and DROPEFFECT_LINK > 0 then Effect := deLink + else Effect := deNone; + DoDragOver(grfKeyState, pt, Effect); + case Effect of + deNone: dwEffect := DROPEFFECT_NONE; + deCopy: dwEffect := DROPEFFECT_COPY; + deMove: dwEffect := DROPEFFECT_MOVE; + deLink: dwEffect := DROPEFFECT_LINK; + end; + Result := S_OK; +end; + +function TfpgOLEDropTarget.Drop(const dataObj: IDataObject; + grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult; +var + Effect: TfpgOLEDragDropEffect; +begin + if dwEffect and DROPEFFECT_COPY > 0 then + Effect := deCopy + else if dwEffect and DROPEFFECT_MOVE > 0 then + Effect := deMove + else if dwEffect and DROPEFFECT_LINK > 0 then + Effect := deLink + else + Effect := deNone; + DoDragDrop(dataObj, grfKeyState, pt, Effect); + Result := S_OK; +end; + +function TfpgOLEDropTarget._AddRef: longint; +begin + Result := 1; +end; + +function TfpgOLEDropTarget._Release: longint; +begin + Result := 1; +end; + +function TfpgOLEDropTarget.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: TGuid; out obj): longint; stdcall; +begin + if GetInterface(IID, Obj) then + Result := 0 + else + Result := E_NOINTERFACE; +end; + +constructor TfpgOLEDropTarget.Create(ADropTargetWidget: TfpgWindowBase); +begin + inherited Create; + FDropTarget := ADropTargetWidget; + FRegistered := False; +end; + +procedure TfpgOLEDropTarget.RegisterDragDrop; +begin + ActiveX.RegisterDragDrop(TfpgWidget(FDropTarget).WinHandle, Self as IDropTarget); + FRegistered := True; +end; + +procedure TfpgOLEDropTarget.RevokeDragDrop; +begin + FRegistered := False; + ActiveX.RevokeDragDrop(TfpgWidget(FDropTarget).WinHandle); +end; + +destructor TfpgOLEDropTarget.Destroy; +begin + if FRegistered then RevokeDragDrop; + inherited; +end; + +procedure TfpgOLEDropTarget.DoDragEnter(DataObj: IDataObject; + KeyState: LongInt; PT: TPoint; var Effect: DWORD); +begin + if Assigned(FOnDragEnter) then begin + FOnDragEnter(Self, DataObj, KeyState, PT, Effect); + end; +end; + +procedure TfpgOLEDropTarget.DoDragOver(KeyState: LongInt; PT: TPoint; + var Effect: TfpgOLEDragDropEffect); +begin + if Assigned(FOnDragOver) then begin + FOnDragOver(Self, KeyState, PT, Effect); + end; +end; + +procedure TfpgOLEDropTarget.DoDragLeave; +begin + if Assigned(FOnDragLeave) then + FOnDragLeave(self); +end; + +procedure TfpgOLEDropTarget.DoDragDrop(DataObj: IDataObject; KeyState: LongInt; + PT: TPoint; Effect: TfpgOLEDragDropEffect); +begin + if Assigned(FOnDragDrop) then begin + FOnDragDrop(Self, DataObj, KeyState, PT, Effect); + end; +end; + +{ TDragFilesTarget } + +function TDragFilesTarget.DoDragAcceptFiles(DataObj: IDataObject): Boolean; +const + FormatEtcHDrop: TFormatEtc = (cfFormat:CF_HDROP;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_HGLOBAL); + FormatEtcFileDescriptor: TFormatEtc = (cfFormat:0;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_HGLOBAL); + FormatEtcFileContents: TFormatEtc = (cfFormat:0;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_ISTREAM); +var + StgMedium: TStgMedium; + DropHandle: HDROP; + EnumFormatEtc: IEnumFORMATETC; + FE: TFormatEtc; + FetchedCount: Longint; + FormatName: array[0..MAX_PATH] of Char; + FileGroupDescriptor: PFileGroupDescriptorA; + I, Count: Integer; + FileDescriptor: TFileDescriptorA; + FileNames: TStringList; +begin + FileNames := TStringList.Create; + try + if Assigned(FOnDragAcceptFiles) then + begin + Result := False; + FormatEtcFileDescriptor.cfFormat := CF_FILEDESCRIPTOR; + FormatEtcFileContents.cfFormat := CF_FILECONTENTS; + + if (DataObj.QueryGetData(FormatEtcHDrop) = S_OK) and + (DataObj.GetData(FormatEtcHDrop,StgMedium) = S_OK) then + begin + DropHandle := StgMedium.hGlobal; + GetFileNamesFromDropHandle(DropHandle, FileNames); + Result := FOnDragAcceptFiles(Self, FileNames); + ReleaseStgMedium(StgMedium); + end + else + if (DataObj.QueryGetData(FormatEtcFileDescriptor) = S_OK) and + (DataObj.QueryGetData(FormatEtcFileContents) = S_OK) and + (DataObj.GetData(FormatEtcFileDescriptor,StgMedium) = S_OK) then + begin + FileGroupDescriptor := GlobalLock(StgMedium.hGlobal); + if FileGroupDescriptor <> nil then + begin + Count := FileGroupDescriptor^.cItems; + I := 0; + while I < Count do + begin + FileDescriptor := FileGroupDescriptor^.fgd[I]; + FileNames.Add(FileDescriptor.cFileName); + Inc(I); + end; + GlobalUnlock(StgMedium.hGlobal); + end; + Result := FOnDragAcceptFiles(Self, FileNames); + ReleaseStgMedium(StgMedium); + end + else + begin +// DataObj.EnumFormatEtc(DATADIR_GET, EnumFormatEtc); +// EnumFormatEtc.Reset; +// while EnumFormatEtc.Next(1, FE, @FetchedCount) = S_OK do begin +// GetClipboardFormatName(FE.cfFormat,FormatName,MAX_PATH); +// ShowMessage(FormatName); +// end; + end; + end + else + begin + Result := True; + end; + finally + FileNames.Free; + end; +end; + +procedure TDragFilesTarget.DoDragEnter(DataObj: IDataObject; + KeyState: LongInt; PT: TPoint; var Effect: DWORD); +begin + FDragAcceptFiles := DoDragAcceptFiles(DataObj); + if FDragAcceptFiles and DoDragAcceptPosition(PT) then + inherited DoDragEnter(DataObj, KeyState, PT, Effect) + else + Effect := DROPEFFECT_NONE; +end; + +procedure TDragFilesTarget.DoDragOver(KeyState: LongInt; PT: TPoint; var Effect: TfpgOLEDragDropEffect); +begin + if FDragAcceptFiles and DoDragAcceptPosition(PT) then + inherited DoDragOver(KeyState, PT, Effect) + else + Effect := deNone; +end; + +procedure TDragFilesTarget.DoDragDrop(DataObj: IDataObject; + KeyState: LongInt; PT: TPoint; Effect: TfpgOLEDragDropEffect); +begin + DoDropFiles(DataObj, PT); + inherited; +end; + +function TDragFilesTarget.DoDragAcceptPosition(PT: TPoint): Boolean; +begin + if Assigned(FOnDragAcceptPosition) then begin + Result := FOnDragAcceptPosition(Self, PT); + end else begin + Result := True; + end; +end; + +procedure TDragFilesTarget.DoDropFiles(DataObj: IDataObject; PT: TPoint); +const + FormatEtcHDrop: TFormatEtc = (cfFormat:CF_HDROP;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_HGLOBAL); + FormatEtcFileDescriptor: TFormatEtc = + (cfFormat:0;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_HGLOBAL); + FormatEtcFileContents: TFormatEtc = + (cfFormat:0;ptd:nil;dwAspect:DVASPECT_CONTENT;lindex:-1;tymed:TYMED_ISTREAM); +var + StgMedium, StgMediumContents: TStgMedium; + DropHandle: HDROP; + FileNames: TStringList; + FileGroupDescriptor: PFileGroupDescriptorA; + I, Count: Integer; + FileDescriptor: TFileDescriptorA; + Path: array[0..MAX_PATH] of Char; + TempFileName: string; +begin + if not Assigned(FOnDropFiles) then Exit; + FileNames := TStringList.Create; + try + FormatEtcFileDescriptor.cfFormat := CF_FILEDESCRIPTOR; + FormatEtcFileContents.cfFormat := CF_FILECONTENTS; + if (DataObj.QueryGetData(FormatEtcHDrop) = S_OK) and + (DataObj.GetData(FormatEtcHDrop,StgMedium) = S_OK) then begin + DropHandle := StgMedium.hGlobal; + GetFileNamesFromDropHandle(DropHandle, FileNames); + FOnDropFiles(Self, PT, FileNames); + ReleaseStgMedium(StgMedium); + end else + if (DataObj.QueryGetData(FormatEtcFileDescriptor) = S_OK) and + (DataObj.QueryGetData(FormatEtcFileContents) = S_OK) and + (DataObj.GetData(FormatEtcFileDescriptor,StgMedium) = S_OK) then begin + GetTempPath(MAX_PATH, Path); + GetTempFileName(Path, 'PXM', 0, Path); + FileGroupDescriptor := GlobalLock(StgMedium.hGlobal); + if FileGroupDescriptor <> nil then begin + Count := FileGroupDescriptor^.cItems; + I := 0; + while I < Count do begin + FileDescriptor := FileGroupDescriptor^.fgd[I]; + TempFileName := ChangeFileExt(Path, ExtractFileExt(FileDescriptor.cFileName)); + FormatEtcFileContents.lindex := I; + if (DataObj.GetData(FormatEtcFileContents,StgMediumContents) = S_OK) then begin + StreamToFile(IStream(StgMediumContents.pstm), TempFileName); + FileNames.Clear; + FileNames.Add(TempFileName); + FOnDropFiles(Self, PT, FileNames); + ReleaseStgMedium(StgMediumContents); + end; + Inc(I); + end; + GlobalUnlock(StgMedium.hGlobal); + end; + FOnDropFiles(Self, PT, FileNames); + ReleaseStgMedium(StgMedium); + ReleaseStgMedium(StgMediumContents); + end; + finally + FileNames.Free; + end; +end; + +procedure TDragFilesTarget.GetFileNamesFromDropHandle(DropHandle: HDROP; SL: TStrings); +var + I: Integer; + Path: array[0..MAX_PATH] of Char; +begin + for I := 0 to DragQueryFile(DropHandle, $FFFFFFFF, nil, 0) do begin + DragQueryFile(DropHandle, I, Path, MAX_PATH); + SL.Add(Path); + end; + DragFinish(DropHandle); +end; + +procedure TDragFilesTarget.StreamToFile(Stream: IStream; const FileName: string); +const + BLOCK_SIZE = 4096; +var + BytesRead: Longint; + FileStream: TFileStream; + Buffer: array[0..BLOCK_SIZE] of Byte; +begin + FileStream := TFileStream.Create(FileName, fmCreate); + try + while (Stream.Read(@Buffer[0], BLOCK_SIZE, @BytesRead) = S_OK) and (BytesRead > 0) do begin + FileStream.Write(Buffer, BytesRead); + end; + finally + FileStream.Free; + end; +end; + +initialization + CF_FILENAMEMAP := RegisterClipboardFormat(CFSTR_FILENAMEMAP); + CF_FILEDESCRIPTOR := RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR); + CF_FILECONTENTS := RegisterClipboardFormat(CFSTR_FILECONTENTS); + +finalization + +end. + diff --git a/src/corelib/gdi/fpgui_toolkit.lpk b/src/corelib/gdi/fpgui_toolkit.lpk index 7654d0d4..2a1fd4ed 100644 --- a/src/corelib/gdi/fpgui_toolkit.lpk +++ b/src/corelib/gdi/fpgui_toolkit.lpk @@ -1,440 +1,440 @@ -<?xml version="1.0"?>
-<CONFIG>
- <Package Version="3">
- <PathDelim Value="\"/>
- <Name Value="fpgui_toolkit"/>
- <AddToProjectUsesSection Value="False"/>
- <Author Value="Graeme Geldenhuys"/>
- <CompilerOptions>
- <Version Value="9"/>
- <PathDelim Value="\"/>
- <SearchPaths>
- <IncludeFiles Value="..\..;..\render\software"/>
- <OtherUnitFiles Value="..;..\..\gui;..\..\gui\db;..\render\software;..\..\reportengine"/>
- <UnitOutputDirectory Value="..\..\..\lib\$(TargetCPU)-$(TargetOS)"/>
- </SearchPaths>
- <Parsing>
- <SyntaxOptions>
- <AllowLabel Value="False"/>
- <CPPInline Value="False"/>
- </SyntaxOptions>
- </Parsing>
- <CodeGeneration>
- <Optimizations>
- <OptimizationLevel Value="0"/>
- </Optimizations>
- </CodeGeneration>
- <Other>
- <CustomOptions Value="-dAggCanvasX"/>
- <CompilerPath Value="$(CompPath)"/>
- </Other>
- </CompilerOptions>
- <Description Value="fpGUI Toolkit"/>
- <License Value="LGPL 2 with static linking exception."/>
- <Version Minor="8"/>
- <Files Count="97">
- <Item1>
- <Filename Value="..\stdimages.inc"/>
- <Type Value="Include"/>
- </Item1>
- <Item2>
- <Filename Value="..\fpg_base.pas"/>
- <UnitName Value="fpg_base"/>
- </Item2>
- <Item3>
- <Filename Value="..\fpg_main.pas"/>
- <UnitName Value="fpg_main"/>
- </Item3>
- <Item4>
- <Filename Value="..\fpg_cmdlineparams.pas"/>
- <UnitName Value="fpg_cmdlineparams"/>
- </Item4>
- <Item5>
- <Filename Value="..\fpg_command_intf.pas"/>
- <UnitName Value="fpg_command_intf"/>
- </Item5>
- <Item6>
- <Filename Value="..\fpg_constants.pas"/>
- <UnitName Value="fpg_constants"/>
- </Item6>
- <Item7>
- <Filename Value="..\fpg_extinterpolation.pas"/>
- <UnitName Value="fpg_extinterpolation"/>
- </Item7>
- <Item8>
- <Filename Value="..\fpg_imagelist.pas"/>
- <UnitName Value="fpg_imagelist"/>
- </Item8>
- <Item9>
- <Filename Value="..\fpg_imgfmt_bmp.pas"/>
- <UnitName Value="fpg_imgfmt_bmp"/>
- </Item9>
- <Item10>
- <Filename Value="..\fpg_msgqueue.inc"/>
- <Type Value="Include"/>
- </Item10>
- <Item11>
- <Filename Value="..\fpg_pofiles.pas"/>
- <UnitName Value="fpg_pofiles"/>
- </Item11>
- <Item12>
- <Filename Value="..\fpg_popupwindow.pas"/>
- <UnitName Value="fpg_popupwindow"/>
- </Item12>
- <Item13>
- <Filename Value="..\fpg_stdimages.pas"/>
- <UnitName Value="fpg_stdimages"/>
- </Item13>
- <Item14>
- <Filename Value="..\fpg_stringhashlist.pas"/>
- <UnitName Value="fpg_stringhashlist"/>
- </Item14>
- <Item15>
- <Filename Value="..\fpg_translations.pas"/>
- <UnitName Value="fpg_translations"/>
- </Item15>
- <Item16>
- <Filename Value="..\fpg_stringutils.pas"/>
- <UnitName Value="fpg_stringutils"/>
- </Item16>
- <Item17>
- <Filename Value="..\fpg_utils.pas"/>
- <UnitName Value="fpg_utils"/>
- </Item17>
- <Item18>
- <Filename Value="..\fpg_widget.pas"/>
- <UnitName Value="fpg_widget"/>
- </Item18>
- <Item19>
- <Filename Value="..\fpg_wuline.pas"/>
- <UnitName Value="fpg_wuline"/>
- </Item19>
- <Item20>
- <Filename Value="..\keys.inc"/>
- <Type Value="Include"/>
- </Item20>
- <Item21>
- <Filename Value="..\lang_af.inc"/>
- <Type Value="Include"/>
- </Item21>
- <Item22>
- <Filename Value="..\lang_en.inc"/>
- <Type Value="Include"/>
- </Item22>
- <Item23>
- <Filename Value="..\lang_fr.inc"/>
- <Type Value="Include"/>
- </Item23>
- <Item24>
- <Filename Value="..\lang_de.inc"/>
- <Type Value="Include"/>
- </Item24>
- <Item25>
- <Filename Value="..\lang_it.inc"/>
- <Type Value="Include"/>
- </Item25>
- <Item26>
- <Filename Value="..\lang_pt.inc"/>
- <Type Value="Include"/>
- </Item26>
- <Item27>
- <Filename Value="..\lang_ru.inc"/>
- <Type Value="Include"/>
- </Item27>
- <Item28>
- <Filename Value="..\lang_es.inc"/>
- <Type Value="Include"/>
- </Item28>
- <Item29>
- <Filename Value="..\predefinedcolors.inc"/>
- <Type Value="Include"/>
- </Item29>
- <Item30>
- <Filename Value="fpg_impl.pas"/>
- <UnitName Value="fpg_impl"/>
- </Item30>
- <Item31>
- <Filename Value="fpg_utils_impl.inc"/>
- <Type Value="Include"/>
- </Item31>
- <Item32>
- <Filename Value="fpg_gdi.pas"/>
- <UnitName Value="fpg_gdi"/>
- </Item32>
- <Item33>
- <Filename Value="fpg_keys_gdi.inc"/>
- <Type Value="Include"/>
- </Item33>
- <Item34>
- <Filename Value="fpg_oledragdrop.pas"/>
- <UnitName Value="fpg_OLEDragDrop"/>
- </Item34>
- <Item35>
- <Filename Value="..\..\gui\promptuserdialog.inc"/>
- <Type Value="Include"/>
- </Item35>
- <Item36>
- <Filename Value="..\..\gui\fpg_animation.pas"/>
- <UnitName Value="fpg_animation"/>
- </Item36>
- <Item37>
- <Filename Value="..\..\gui\fpg_basegrid.pas"/>
- <UnitName Value="fpg_basegrid"/>
- </Item37>
- <Item38>
- <Filename Value="..\..\gui\fpg_button.pas"/>
- <UnitName Value="fpg_button"/>
- </Item38>
- <Item39>
- <Filename Value="..\..\gui\fpg_checkbox.pas"/>
- <UnitName Value="fpg_checkbox"/>
- </Item39>
- <Item40>
- <Filename Value="..\..\gui\fpg_combobox.pas"/>
- <UnitName Value="fpg_combobox"/>
- </Item40>
- <Item41>
- <Filename Value="..\..\gui\fpg_customgrid.pas"/>
- <UnitName Value="fpg_customgrid"/>
- </Item41>
- <Item42>
- <Filename Value="..\..\gui\fpg_dialogs.pas"/>
- <UnitName Value="fpg_dialogs"/>
- </Item42>
- <Item43>
- <Filename Value="..\..\gui\fpg_editcombo.pas"/>
- <UnitName Value="fpg_editcombo"/>
- </Item43>
- <Item44>
- <Filename Value="..\..\gui\fpg_edit.pas"/>
- <UnitName Value="fpg_edit"/>
- </Item44>
- <Item45>
- <Filename Value="..\..\gui\fpg_form.pas"/>
- <UnitName Value="fpg_form"/>
- </Item45>
- <Item46>
- <Filename Value="..\..\gui\fpg_gauge.pas"/>
- <UnitName Value="fpg_gauge"/>
- </Item46>
- <Item47>
- <Filename Value="..\..\gui\fpg_grid.pas"/>
- <UnitName Value="fpg_grid"/>
- </Item47>
- <Item48>
- <Filename Value="..\..\gui\fpg_hyperlink.pas"/>
- <UnitName Value="fpg_hyperlink"/>
- </Item48>
- <Item49>
- <Filename Value="..\..\gui\fpg_iniutils.pas"/>
- <UnitName Value="fpg_iniutils"/>
- </Item49>
- <Item50>
- <Filename Value="..\..\gui\fpg_label.pas"/>
- <UnitName Value="fpg_label"/>
- </Item50>
- <Item51>
- <Filename Value="..\..\gui\fpg_listbox.pas"/>
- <UnitName Value="fpg_listbox"/>
- </Item51>
- <Item52>
- <Filename Value="..\..\gui\fpg_listview.pas"/>
- <UnitName Value="fpg_listview"/>
- </Item52>
- <Item53>
- <Filename Value="..\..\gui\fpg_memo.pas"/>
- <UnitName Value="fpg_memo"/>
- </Item53>
- <Item54>
- <Filename Value="..\..\gui\fpg_menu.pas"/>
- <UnitName Value="fpg_menu"/>
- </Item54>
- <Item55>
- <Filename Value="..\..\gui\fpg_mru.pas"/>
- <UnitName Value="fpg_mru"/>
- </Item55>
- <Item56>
- <Filename Value="..\..\gui\fpg_panel.pas"/>
- <UnitName Value="fpg_panel"/>
- </Item56>
- <Item57>
- <Filename Value="..\..\gui\fpg_popupcalendar.pas"/>
- <UnitName Value="fpg_popupcalendar"/>
- </Item57>
- <Item58>
- <Filename Value="..\..\gui\fpg_progressbar.pas"/>
- <UnitName Value="fpg_progressbar"/>
- </Item58>
- <Item59>
- <Filename Value="..\..\gui\fpg_radiobutton.pas"/>
- <UnitName Value="fpg_radiobutton"/>
- </Item59>
- <Item60>
- <Filename Value="..\..\gui\fpg_scrollbar.pas"/>
- <UnitName Value="fpg_scrollbar"/>
- </Item60>
- <Item61>
- <Filename Value="..\..\gui\fpg_style.pas"/>
- <UnitName Value="fpg_style"/>
- </Item61>
- <Item62>
- <Filename Value="..\..\gui\fpg_tab.pas"/>
- <UnitName Value="fpg_tab"/>
- </Item62>
- <Item63>
- <Filename Value="..\..\gui\fpg_trackbar.pas"/>
- <UnitName Value="fpg_trackbar"/>
- </Item63>
- <Item64>
- <Filename Value="..\..\gui\fpg_tree.pas"/>
- <UnitName Value="fpg_tree"/>
- </Item64>
- <Item65>
- <Filename Value="..\..\gui\logo.inc"/>
- <Type Value="Include"/>
- </Item65>
- <Item66>
- <Filename Value="..\..\gui\messagedialog.inc"/>
- <Type Value="Include"/>
- </Item66>
- <Item67>
- <Filename Value="..\..\gui\newdirdialog.inc"/>
- <Type Value="Include"/>
- </Item67>
- <Item68>
- <Filename Value="..\..\gui\selectdirdialog.inc"/>
- <Type Value="Include"/>
- </Item68>
- <Item69>
- <Filename Value="..\..\gui\db\fpgui_db.pas"/>
- <UnitName Value="fpgui_db"/>
- </Item69>
- <Item70>
- <Filename Value="..\..\gui\fpg_splitter.pas"/>
- <UnitName Value="fpg_splitter"/>
- </Item70>
- <Item71>
- <Filename Value="..\..\gui\fpg_hint.pas"/>
- <UnitName Value="fpg_hint"/>
- </Item71>
- <Item72>
- <Filename Value="..\..\gui\fpg_spinedit.pas"/>
- <UnitName Value="fpg_spinedit"/>
- </Item72>
- <Item73>
- <Filename Value="..\fpg_extgraphics.pas"/>
- <UnitName Value="fpg_extgraphics"/>
- </Item73>
- <Item74>
- <Filename Value="..\..\gui\charmapdialog.inc"/>
- <Type Value="Include"/>
- </Item74>
- <Item75>
- <Filename Value="..\..\gui\fpg_colormapping.pas"/>
- <UnitName Value="fpg_ColorMapping"/>
- </Item75>
- <Item76>
- <Filename Value="..\..\gui\fpg_colorwheel.pas"/>
- <UnitName Value="fpg_ColorWheel"/>
- </Item76>
- <Item77>
- <Filename Value="fpg_interface.pas"/>
- <UnitName Value="fpg_interface"/>
- </Item77>
- <Item78>
- <Filename Value="..\..\gui\fpg_editbtn.pas"/>
- <UnitName Value="fpg_editbtn"/>
- </Item78>
- <Item79>
- <Filename Value="..\..\gui\colordialog.inc"/>
- <Type Value="Include"/>
- </Item79>
- <Item80>
- <Filename Value="..\fpg_imgfmt_jpg.pas"/>
- <UnitName Value="fpg_imgfmt_jpg"/>
- </Item80>
- <Item81>
- <Filename Value="..\..\gui\inputquerydialog.inc"/>
- <Type Value="Include"/>
- </Item81>
- <Item82>
- <Filename Value="..\fpg_imgutils.pas"/>
- <UnitName Value="fpg_imgutils"/>
- </Item82>
- <Item83>
- <Filename Value="..\..\VERSION_FILE.inc"/>
- <Type Value="Include"/>
- </Item83>
- <Item84>
- <Filename Value="..\..\gui\fpg_stylemanager.pas"/>
- <UnitName Value="fpg_stylemanager"/>
- </Item84>
- <Item85>
- <Filename Value="..\..\gui\fpg_style_win2k.pas"/>
- <UnitName Value="fpg_style_win2k"/>
- </Item85>
- <Item86>
- <Filename Value="..\..\gui\fpg_style_motif.pas"/>
- <UnitName Value="fpg_style_motif"/>
- </Item86>
- <Item87>
- <Filename Value="..\..\gui\fpg_style_clearlooks.pas"/>
- <UnitName Value="fpg_style_clearlooks"/>
- </Item87>
- <Item88>
- <Filename Value="..\..\gui\fpg_style_bluecurve.pas"/>
- <UnitName Value="fpg_style_bluecurve"/>
- </Item88>
- <Item89>
- <Filename Value="..\..\gui\fpg_style_bitmap.pas"/>
- <UnitName Value="fpg_style_bitmap"/>
- </Item89>
- <Item90>
- <Filename Value="..\..\gui\fpg_readonly.pas"/>
- <UnitName Value="fpg_readonly"/>
- </Item90>
- <Item91>
- <Filename Value="..\fpg_imgfmt_png.pas"/>
- <UnitName Value="fpg_imgfmt_png"/>
- </Item91>
- <Item92>
- <Filename Value="..\..\reportengine\u_command.pas"/>
- <UnitName Value="U_Command"/>
- </Item92>
- <Item93>
- <Filename Value="..\..\reportengine\u_pdf.pas"/>
- <UnitName Value="U_Pdf"/>
- </Item93>
- <Item94>
- <Filename Value="..\..\reportengine\u_report.pas"/>
- <UnitName Value="U_Report"/>
- </Item94>
- <Item95>
- <Filename Value="..\..\reportengine\u_reportimages.pas"/>
- <UnitName Value="U_ReportImages"/>
- </Item95>
- <Item96>
- <Filename Value="..\..\reportengine\u_visu.pas"/>
- <UnitName Value="U_Visu"/>
- </Item96>
- <Item97>
- <Filename Value="..\..\gui\fpg_trayicon.pas"/>
- <UnitName Value="fpg_trayicon"/>
- </Item97>
- </Files>
- <LazDoc Paths="../../../docs/xml/corelib;../../../docs/xml/corelib/x11;../../../docs/xml/corelib/gdi;../../../docs/xml/gui"/>
- <RequiredPkgs Count="1">
- <Item1>
- <PackageName Value="FCL"/>
- <MinVersion Major="1" Valid="True"/>
- </Item1>
- </RequiredPkgs>
- <UsageOptions>
- <UnitPath Value="$(PkgOutDir)"/>
- </UsageOptions>
- <PublishOptions>
- <Version Value="2"/>
- <IgnoreBinaries Value="False"/>
- </PublishOptions>
- </Package>
-</CONFIG>
+<?xml version="1.0"?> +<CONFIG> + <Package Version="3"> + <PathDelim Value="\"/> + <Name Value="fpgui_toolkit"/> + <AddToProjectUsesSection Value="False"/> + <Author Value="Graeme Geldenhuys"/> + <CompilerOptions> + <Version Value="9"/> + <PathDelim Value="\"/> + <SearchPaths> + <IncludeFiles Value="..\..;..\render\software"/> + <OtherUnitFiles Value="..;..\..\gui;..\..\gui\db;..\render\software;..\..\reportengine"/> + <UnitOutputDirectory Value="..\..\..\lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <AllowLabel Value="False"/> + <CPPInline Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <Optimizations> + <OptimizationLevel Value="0"/> + </Optimizations> + </CodeGeneration> + <Other> + <CustomOptions Value="-dAggCanvasX"/> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + <Description Value="fpGUI Toolkit"/> + <License Value="LGPL 2 with static linking exception."/> + <Version Minor="8"/> + <Files Count="97"> + <Item1> + <Filename Value="..\stdimages.inc"/> + <Type Value="Include"/> + </Item1> + <Item2> + <Filename Value="..\fpg_base.pas"/> + <UnitName Value="fpg_base"/> + </Item2> + <Item3> + <Filename Value="..\fpg_main.pas"/> + <UnitName Value="fpg_main"/> + </Item3> + <Item4> + <Filename Value="..\fpg_cmdlineparams.pas"/> + <UnitName Value="fpg_cmdlineparams"/> + </Item4> + <Item5> + <Filename Value="..\fpg_command_intf.pas"/> + <UnitName Value="fpg_command_intf"/> + </Item5> + <Item6> + <Filename Value="..\fpg_constants.pas"/> + <UnitName Value="fpg_constants"/> + </Item6> + <Item7> + <Filename Value="..\fpg_extinterpolation.pas"/> + <UnitName Value="fpg_extinterpolation"/> + </Item7> + <Item8> + <Filename Value="..\fpg_imagelist.pas"/> + <UnitName Value="fpg_imagelist"/> + </Item8> + <Item9> + <Filename Value="..\fpg_imgfmt_bmp.pas"/> + <UnitName Value="fpg_imgfmt_bmp"/> + </Item9> + <Item10> + <Filename Value="..\fpg_msgqueue.inc"/> + <Type Value="Include"/> + </Item10> + <Item11> + <Filename Value="..\fpg_pofiles.pas"/> + <UnitName Value="fpg_pofiles"/> + </Item11> + <Item12> + <Filename Value="..\fpg_popupwindow.pas"/> + <UnitName Value="fpg_popupwindow"/> + </Item12> + <Item13> + <Filename Value="..\fpg_stdimages.pas"/> + <UnitName Value="fpg_stdimages"/> + </Item13> + <Item14> + <Filename Value="..\fpg_stringhashlist.pas"/> + <UnitName Value="fpg_stringhashlist"/> + </Item14> + <Item15> + <Filename Value="..\fpg_translations.pas"/> + <UnitName Value="fpg_translations"/> + </Item15> + <Item16> + <Filename Value="..\fpg_stringutils.pas"/> + <UnitName Value="fpg_stringutils"/> + </Item16> + <Item17> + <Filename Value="..\fpg_utils.pas"/> + <UnitName Value="fpg_utils"/> + </Item17> + <Item18> + <Filename Value="..\fpg_widget.pas"/> + <UnitName Value="fpg_widget"/> + </Item18> + <Item19> + <Filename Value="..\fpg_wuline.pas"/> + <UnitName Value="fpg_wuline"/> + </Item19> + <Item20> + <Filename Value="..\keys.inc"/> + <Type Value="Include"/> + </Item20> + <Item21> + <Filename Value="..\lang_af.inc"/> + <Type Value="Include"/> + </Item21> + <Item22> + <Filename Value="..\lang_en.inc"/> + <Type Value="Include"/> + </Item22> + <Item23> + <Filename Value="..\lang_fr.inc"/> + <Type Value="Include"/> + </Item23> + <Item24> + <Filename Value="..\lang_de.inc"/> + <Type Value="Include"/> + </Item24> + <Item25> + <Filename Value="..\lang_it.inc"/> + <Type Value="Include"/> + </Item25> + <Item26> + <Filename Value="..\lang_pt.inc"/> + <Type Value="Include"/> + </Item26> + <Item27> + <Filename Value="..\lang_ru.inc"/> + <Type Value="Include"/> + </Item27> + <Item28> + <Filename Value="..\lang_es.inc"/> + <Type Value="Include"/> + </Item28> + <Item29> + <Filename Value="..\predefinedcolors.inc"/> + <Type Value="Include"/> + </Item29> + <Item30> + <Filename Value="fpg_impl.pas"/> + <UnitName Value="fpg_impl"/> + </Item30> + <Item31> + <Filename Value="fpg_utils_impl.inc"/> + <Type Value="Include"/> + </Item31> + <Item32> + <Filename Value="fpg_gdi.pas"/> + <UnitName Value="fpg_gdi"/> + </Item32> + <Item33> + <Filename Value="fpg_keys_gdi.inc"/> + <Type Value="Include"/> + </Item33> + <Item34> + <Filename Value="fpg_oledragdrop.pas"/> + <UnitName Value="fpg_OLEDragDrop"/> + </Item34> + <Item35> + <Filename Value="..\..\gui\promptuserdialog.inc"/> + <Type Value="Include"/> + </Item35> + <Item36> + <Filename Value="..\..\gui\fpg_animation.pas"/> + <UnitName Value="fpg_animation"/> + </Item36> + <Item37> + <Filename Value="..\..\gui\fpg_basegrid.pas"/> + <UnitName Value="fpg_basegrid"/> + </Item37> + <Item38> + <Filename Value="..\..\gui\fpg_button.pas"/> + <UnitName Value="fpg_button"/> + </Item38> + <Item39> + <Filename Value="..\..\gui\fpg_checkbox.pas"/> + <UnitName Value="fpg_checkbox"/> + </Item39> + <Item40> + <Filename Value="..\..\gui\fpg_combobox.pas"/> + <UnitName Value="fpg_combobox"/> + </Item40> + <Item41> + <Filename Value="..\..\gui\fpg_customgrid.pas"/> + <UnitName Value="fpg_customgrid"/> + </Item41> + <Item42> + <Filename Value="..\..\gui\fpg_dialogs.pas"/> + <UnitName Value="fpg_dialogs"/> + </Item42> + <Item43> + <Filename Value="..\..\gui\fpg_editcombo.pas"/> + <UnitName Value="fpg_editcombo"/> + </Item43> + <Item44> + <Filename Value="..\..\gui\fpg_edit.pas"/> + <UnitName Value="fpg_edit"/> + </Item44> + <Item45> + <Filename Value="..\..\gui\fpg_form.pas"/> + <UnitName Value="fpg_form"/> + </Item45> + <Item46> + <Filename Value="..\..\gui\fpg_gauge.pas"/> + <UnitName Value="fpg_gauge"/> + </Item46> + <Item47> + <Filename Value="..\..\gui\fpg_grid.pas"/> + <UnitName Value="fpg_grid"/> + </Item47> + <Item48> + <Filename Value="..\..\gui\fpg_hyperlink.pas"/> + <UnitName Value="fpg_hyperlink"/> + </Item48> + <Item49> + <Filename Value="..\..\gui\fpg_iniutils.pas"/> + <UnitName Value="fpg_iniutils"/> + </Item49> + <Item50> + <Filename Value="..\..\gui\fpg_label.pas"/> + <UnitName Value="fpg_label"/> + </Item50> + <Item51> + <Filename Value="..\..\gui\fpg_listbox.pas"/> + <UnitName Value="fpg_listbox"/> + </Item51> + <Item52> + <Filename Value="..\..\gui\fpg_listview.pas"/> + <UnitName Value="fpg_listview"/> + </Item52> + <Item53> + <Filename Value="..\..\gui\fpg_memo.pas"/> + <UnitName Value="fpg_memo"/> + </Item53> + <Item54> + <Filename Value="..\..\gui\fpg_menu.pas"/> + <UnitName Value="fpg_menu"/> + </Item54> + <Item55> + <Filename Value="..\..\gui\fpg_mru.pas"/> + <UnitName Value="fpg_mru"/> + </Item55> + <Item56> + <Filename Value="..\..\gui\fpg_panel.pas"/> + <UnitName Value="fpg_panel"/> + </Item56> + <Item57> + <Filename Value="..\..\gui\fpg_popupcalendar.pas"/> + <UnitName Value="fpg_popupcalendar"/> + </Item57> + <Item58> + <Filename Value="..\..\gui\fpg_progressbar.pas"/> + <UnitName Value="fpg_progressbar"/> + </Item58> + <Item59> + <Filename Value="..\..\gui\fpg_radiobutton.pas"/> + <UnitName Value="fpg_radiobutton"/> + </Item59> + <Item60> + <Filename Value="..\..\gui\fpg_scrollbar.pas"/> + <UnitName Value="fpg_scrollbar"/> + </Item60> + <Item61> + <Filename Value="..\..\gui\fpg_style.pas"/> + <UnitName Value="fpg_style"/> + </Item61> + <Item62> + <Filename Value="..\..\gui\fpg_tab.pas"/> + <UnitName Value="fpg_tab"/> + </Item62> + <Item63> + <Filename Value="..\..\gui\fpg_trackbar.pas"/> + <UnitName Value="fpg_trackbar"/> + </Item63> + <Item64> + <Filename Value="..\..\gui\fpg_tree.pas"/> + <UnitName Value="fpg_tree"/> + </Item64> + <Item65> + <Filename Value="..\..\gui\logo.inc"/> + <Type Value="Include"/> + </Item65> + <Item66> + <Filename Value="..\..\gui\messagedialog.inc"/> + <Type Value="Include"/> + </Item66> + <Item67> + <Filename Value="..\..\gui\newdirdialog.inc"/> + <Type Value="Include"/> + </Item67> + <Item68> + <Filename Value="..\..\gui\selectdirdialog.inc"/> + <Type Value="Include"/> + </Item68> + <Item69> + <Filename Value="..\..\gui\db\fpgui_db.pas"/> + <UnitName Value="fpgui_db"/> + </Item69> + <Item70> + <Filename Value="..\..\gui\fpg_splitter.pas"/> + <UnitName Value="fpg_splitter"/> + </Item70> + <Item71> + <Filename Value="..\..\gui\fpg_hint.pas"/> + <UnitName Value="fpg_hint"/> + </Item71> + <Item72> + <Filename Value="..\..\gui\fpg_spinedit.pas"/> + <UnitName Value="fpg_spinedit"/> + </Item72> + <Item73> + <Filename Value="..\fpg_extgraphics.pas"/> + <UnitName Value="fpg_extgraphics"/> + </Item73> + <Item74> + <Filename Value="..\..\gui\charmapdialog.inc"/> + <Type Value="Include"/> + </Item74> + <Item75> + <Filename Value="..\..\gui\fpg_colormapping.pas"/> + <UnitName Value="fpg_ColorMapping"/> + </Item75> + <Item76> + <Filename Value="..\..\gui\fpg_colorwheel.pas"/> + <UnitName Value="fpg_ColorWheel"/> + </Item76> + <Item77> + <Filename Value="fpg_interface.pas"/> + <UnitName Value="fpg_interface"/> + </Item77> + <Item78> + <Filename Value="..\..\gui\fpg_editbtn.pas"/> + <UnitName Value="fpg_editbtn"/> + </Item78> + <Item79> + <Filename Value="..\..\gui\colordialog.inc"/> + <Type Value="Include"/> + </Item79> + <Item80> + <Filename Value="..\fpg_imgfmt_jpg.pas"/> + <UnitName Value="fpg_imgfmt_jpg"/> + </Item80> + <Item81> + <Filename Value="..\..\gui\inputquerydialog.inc"/> + <Type Value="Include"/> + </Item81> + <Item82> + <Filename Value="..\fpg_imgutils.pas"/> + <UnitName Value="fpg_imgutils"/> + </Item82> + <Item83> + <Filename Value="..\..\VERSION_FILE.inc"/> + <Type Value="Include"/> + </Item83> + <Item84> + <Filename Value="..\..\gui\fpg_stylemanager.pas"/> + <UnitName Value="fpg_stylemanager"/> + </Item84> + <Item85> + <Filename Value="..\..\gui\fpg_style_win2k.pas"/> + <UnitName Value="fpg_style_win2k"/> + </Item85> + <Item86> + <Filename Value="..\..\gui\fpg_style_motif.pas"/> + <UnitName Value="fpg_style_motif"/> + </Item86> + <Item87> + <Filename Value="..\..\gui\fpg_style_clearlooks.pas"/> + <UnitName Value="fpg_style_clearlooks"/> + </Item87> + <Item88> + <Filename Value="..\..\gui\fpg_style_bluecurve.pas"/> + <UnitName Value="fpg_style_bluecurve"/> + </Item88> + <Item89> + <Filename Value="..\..\gui\fpg_style_bitmap.pas"/> + <UnitName Value="fpg_style_bitmap"/> + </Item89> + <Item90> + <Filename Value="..\..\gui\fpg_readonly.pas"/> + <UnitName Value="fpg_readonly"/> + </Item90> + <Item91> + <Filename Value="..\fpg_imgfmt_png.pas"/> + <UnitName Value="fpg_imgfmt_png"/> + </Item91> + <Item92> + <Filename Value="..\..\reportengine\u_command.pas"/> + <UnitName Value="U_Command"/> + </Item92> + <Item93> + <Filename Value="..\..\reportengine\u_pdf.pas"/> + <UnitName Value="U_Pdf"/> + </Item93> + <Item94> + <Filename Value="..\..\reportengine\u_report.pas"/> + <UnitName Value="U_Report"/> + </Item94> + <Item95> + <Filename Value="..\..\reportengine\u_reportimages.pas"/> + <UnitName Value="U_ReportImages"/> + </Item95> + <Item96> + <Filename Value="..\..\reportengine\u_visu.pas"/> + <UnitName Value="U_Visu"/> + </Item96> + <Item97> + <Filename Value="..\..\gui\fpg_trayicon.pas"/> + <UnitName Value="fpg_trayicon"/> + </Item97> + </Files> + <LazDoc Paths="../../../docs/xml/corelib;../../../docs/xml/corelib/x11;../../../docs/xml/corelib/gdi;../../../docs/xml/gui"/> + <RequiredPkgs Count="1"> + <Item1> + <PackageName Value="FCL"/> + <MinVersion Major="1" Valid="True"/> + </Item1> + </RequiredPkgs> + <UsageOptions> + <UnitPath Value="$(PkgOutDir)"/> + </UsageOptions> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + </PublishOptions> + </Package> +</CONFIG> diff --git a/src/corelib/gdi/fpgui_toolkit.pas b/src/corelib/gdi/fpgui_toolkit.pas index 7496bb18..b4b6aa8f 100644 --- a/src/corelib/gdi/fpgui_toolkit.pas +++ b/src/corelib/gdi/fpgui_toolkit.pas @@ -1,28 +1,28 @@ -{ This file was automatically created by Lazarus. Do not edit!
- This source is only used to compile and install the package.
- }
-
-unit fpgui_toolkit;
-
-interface
-
-uses
- fpg_base, fpg_main, fpg_cmdlineparams, fpg_command_intf, fpg_constants,
- fpg_extinterpolation, fpg_imagelist, fpg_imgfmt_bmp, fpg_pofiles,
- fpg_popupwindow, fpg_stdimages, fpg_stringhashlist, fpg_translations,
- fpg_stringutils, fpg_utils, fpg_widget, fpg_wuline, fpg_impl, fpg_gdi,
- fpg_OLEDragDrop, fpg_animation, fpg_basegrid, fpg_button, fpg_checkbox,
- fpg_combobox, fpg_customgrid, fpg_dialogs, fpg_editcombo, fpg_edit,
- fpg_form, fpg_gauge, fpg_grid, fpg_hyperlink, fpg_iniutils, fpg_label,
- fpg_listbox, fpg_listview, fpg_memo, fpg_menu, fpg_mru, fpg_panel,
- fpg_popupcalendar, fpg_progressbar, fpg_radiobutton, fpg_scrollbar,
- fpg_style, fpg_tab, fpg_trackbar, fpg_tree, fpgui_db, fpg_splitter,
- fpg_hint, fpg_spinedit, fpg_extgraphics, fpg_ColorMapping, fpg_ColorWheel,
- fpg_interface, fpg_editbtn, fpg_imgfmt_jpg, fpg_imgutils, fpg_stylemanager,
- fpg_style_win2k, fpg_style_motif, fpg_style_clearlooks, fpg_style_bluecurve,
- fpg_style_bitmap, fpg_readonly, fpg_imgfmt_png, U_Command, U_Pdf, U_Report,
- U_ReportImages, U_Visu, fpg_trayicon;
-
-implementation
-
-end.
+{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit fpgui_toolkit; + +interface + +uses + fpg_base, fpg_main, fpg_cmdlineparams, fpg_command_intf, fpg_constants, + fpg_extinterpolation, fpg_imagelist, fpg_imgfmt_bmp, fpg_pofiles, + fpg_popupwindow, fpg_stdimages, fpg_stringhashlist, fpg_translations, + fpg_stringutils, fpg_utils, fpg_widget, fpg_wuline, fpg_impl, fpg_gdi, + fpg_OLEDragDrop, fpg_animation, fpg_basegrid, fpg_button, fpg_checkbox, + fpg_combobox, fpg_customgrid, fpg_dialogs, fpg_editcombo, fpg_edit, + fpg_form, fpg_gauge, fpg_grid, fpg_hyperlink, fpg_iniutils, fpg_label, + fpg_listbox, fpg_listview, fpg_memo, fpg_menu, fpg_mru, fpg_panel, + fpg_popupcalendar, fpg_progressbar, fpg_radiobutton, fpg_scrollbar, + fpg_style, fpg_tab, fpg_trackbar, fpg_tree, fpgui_db, fpg_splitter, + fpg_hint, fpg_spinedit, fpg_extgraphics, fpg_ColorMapping, fpg_ColorWheel, + fpg_interface, fpg_editbtn, fpg_imgfmt_jpg, fpg_imgutils, fpg_stylemanager, + fpg_style_win2k, fpg_style_motif, fpg_style_clearlooks, fpg_style_bluecurve, + fpg_style_bitmap, fpg_readonly, fpg_imgfmt_png, U_Command, U_Pdf, U_Report, + U_ReportImages, U_Visu, fpg_trayicon; + +implementation + +end. diff --git a/src/corelib/render/software/agg-demos/expat-wrap/linux/ReadMe_Linux.txt b/src/corelib/render/software/agg-demos/expat-wrap/linux/ReadMe_Linux.txt index 6524b3af..08af5394 100644 --- a/src/corelib/render/software/agg-demos/expat-wrap/linux/ReadMe_Linux.txt +++ b/src/corelib/render/software/agg-demos/expat-wrap/linux/ReadMe_Linux.txt @@ -1,33 +1,33 @@ - How to build Expat under Linux
- (tested on RedHat 7.3)
-
-1) After having extracted expat-1.95.6.tar to the expat directory,
- or checked the 1.95.6 release out of the CVS repository, run
- the configure script "./buildconf.sh" from the build directory.
- This will need autoconf 2.52 or later and libtool 1.4 installed,
- which are not part of the standard installation of RedHat 7.3!
-
-2a) Build for UTF8 output:
- From the build directory) run "./configure", followed by "make",
- then change to root (su root) and run "make install".
-
-2b) Build for UTF16 output:
- - maybe run "make clean" first
- - for 16 bit wchar_t output (incl. version and message strings),
- run
- ./configure CFLAGS="-g -O2 -fshort-wchar" CPPFLAGS=-DXML_UNICODE_WCHAR_T
- or for unsigned short output (but version and message strings as 8bit chars),
- run
- ./configure CPPFLAGS=-DXML_UNICODE
- - Then edit the MakeFile: change "LIBRARY = libexpat.la" to
- "LIBRARY = libexpatw.la"
- - Finally, run "make buildlib" and "make installlib"
- (the latter with root privileges)
-
-Notes:
- - The libraries are installed as: "libexpat.so" (UTF8) and "libexpatw.so" (UTF16),
- which are usually symlinks pointing to the active version of Expat, which
- in this case would be "libexpat.so.0.4.0" and "libexpatw.so.0.4.0".
- - don't forget to run /sbin/ldconfig to configure the dynamic linker
- - one can combine two of the steps by running "make buildlib LIBRARY=libexpatw.la"
-
+ How to build Expat under Linux + (tested on RedHat 7.3) + +1) After having extracted expat-1.95.6.tar to the expat directory, + or checked the 1.95.6 release out of the CVS repository, run + the configure script "./buildconf.sh" from the build directory. + This will need autoconf 2.52 or later and libtool 1.4 installed, + which are not part of the standard installation of RedHat 7.3! + +2a) Build for UTF8 output: + From the build directory) run "./configure", followed by "make", + then change to root (su root) and run "make install". + +2b) Build for UTF16 output: + - maybe run "make clean" first + - for 16 bit wchar_t output (incl. version and message strings), + run + ./configure CFLAGS="-g -O2 -fshort-wchar" CPPFLAGS=-DXML_UNICODE_WCHAR_T + or for unsigned short output (but version and message strings as 8bit chars), + run + ./configure CPPFLAGS=-DXML_UNICODE + - Then edit the MakeFile: change "LIBRARY = libexpat.la" to + "LIBRARY = libexpatw.la" + - Finally, run "make buildlib" and "make installlib" + (the latter with root privileges) + +Notes: + - The libraries are installed as: "libexpat.so" (UTF8) and "libexpatw.so" (UTF16), + which are usually symlinks pointing to the active version of Expat, which + in this case would be "libexpat.so.0.4.0" and "libexpatw.so.0.4.0". + - don't forget to run /sbin/ldconfig to configure the dynamic linker + - one can combine two of the steps by running "make buildlib LIBRARY=libexpatw.la" + diff --git a/src/corelib/render/software/agg-demos/svg/tiger.svg b/src/corelib/render/software/agg-demos/svg/tiger.svg index 234c1673..31e5abc0 100644 --- a/src/corelib/render/software/agg-demos/svg/tiger.svg +++ b/src/corelib/render/software/agg-demos/svg/tiger.svg @@ -1,728 +1,728 @@ -<?xml version = "1.0" standalone = "no"?>
-<!DOCTYPE svg SYSTEM "svg-19990812.dtd">
-<svg width = "600px" height="600px">
-<title>A less cute tiger
-</title>
-<g transform="translate(190,150)">
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-122.304 84.285C-122.304 84.285 -122.203 86.179 -123.027 86.16C-123.851 86.141 -140.305 38.066 -160.833 40.309C-160.833 40.309 -143.05 32.956 -122.304 84.285z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-118.774 81.262C-118.774 81.262 -119.323 83.078 -120.092 82.779C-120.86 82.481 -119.977 31.675 -140.043 26.801C-140.043 26.801 -120.82 25.937 -118.774 81.262z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-91.284 123.59C-91.284 123.59 -89.648 124.55 -90.118 125.227C-90.589 125.904 -139.763 113.102 -149.218 131.459C-149.218 131.459 -145.539 112.572 -91.284 123.59z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-94.093 133.801C-94.093 133.801 -92.237 134.197 -92.471 134.988C-92.704 135.779 -143.407 139.121 -146.597 159.522C-146.597 159.522 -149.055 140.437 -94.093 133.801z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-98.304 128.276C-98.304 128.276 -96.526 128.939 -96.872 129.687C-97.218 130.435 -147.866 126.346 -153.998 146.064C-153.998 146.064 -153.646 126.825 -98.304 128.276z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-109.009 110.072C-109.009 110.072 -107.701 111.446 -108.34 111.967C-108.979 112.488 -152.722 86.634 -166.869 101.676C-166.869 101.676 -158.128 84.533 -109.009 110.072z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-116.554 114.263C-116.554 114.263 -115.098 115.48 -115.674 116.071C-116.25 116.661 -162.638 95.922 -174.992 112.469C-174.992 112.469 -168.247 94.447 -116.554 114.263z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-119.154 118.335C-119.154 118.335 -117.546 119.343 -118.036 120.006C-118.526 120.669 -167.308 106.446 -177.291 124.522C-177.291 124.522 -173.066 105.749 -119.154 118.335z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-108.42 118.949C-108.42 118.949 -107.298 120.48 -107.999 120.915C-108.7 121.35 -148.769 90.102 -164.727 103.207C-164.727 103.207 -153.862 87.326 -108.42 118.949z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-128.2 90C-128.2 90 -127.6 91.8 -128.4 92C-129.2 92.2 -157.8 50.2 -177.001 57.8C-177.001 57.8 -161.8 46 -128.2 90z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-127.505 96.979C-127.505 96.979 -126.53 98.608 -127.269 98.975C-128.007 99.343 -164.992 64.499 -182.101 76.061C-182.101 76.061 -169.804 61.261 -127.505 96.979z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
- <path d="M-127.62 101.349C-127.62 101.349 -126.498 102.88 -127.199 103.315C-127.9 103.749 -167.969 72.502 -183.927 85.607C-183.927 85.607 -173.062 69.726 -127.62 101.349z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000">
- <path d="M-129.83 103.065C-129.327 109.113 -128.339 115.682 -126.6 118.801C-126.6 118.801 -130.2 131.201 -121.4 144.401C-121.4 144.401 -121.8 151.601 -120.2 154.801C-120.2 154.801 -116.2 163.201 -111.4 164.001C-107.516 164.648 -98.793 167.717 -88.932 169.121C-88.932 169.121 -71.8 183.201 -75 196.001C-75 196.001 -75.4 212.401 -79 214.001C-79 214.001 -67.4 202.801 -77 219.601L-81.4 238.401C-81.4 238.401 -55.8 216.801 -71.4 235.201L-81.4 261.201C-81.4 261.201 -61.8 242.801 -69 251.201L-72.2 260.001C-72.2 260.001 -29 232.801 -59.8 262.401C-59.8 262.401 -51.8 258.801 -47.4 261.601C-47.4 261.601 -40.6 260.401 -41.4 262.001C-41.4 262.001 -62.2 272.401 -65.8 290.801C-65.8 290.801 -57.4 280.801 -60.6 291.601L-60.2 303.201C-60.2 303.201 -56.2 281.601 -56.6 319.201C-56.6 319.201 -37.4 301.201 -49 322.001L-49 338.801C-49 338.801 -33.8 322.401 -40.2 335.201C-40.2 335.201 -30.2 326.401 -34.2 341.601C-34.2 341.601 -35 352.001 -30.6 340.801C-30.6 340.801 -14.6 310.201 -20.6 336.401C-20.6 336.401 -21.4 355.601 -16.6 340.801C-16.6 340.801 -16.2 351.201 -7 358.401C-7 358.401 -8.2 307.601 4.6 343.601L8.6 360.001C8.6 360.001 11.4 350.801 11 345.601C11 345.601 25.8 329.201 19 353.601C19 353.601 34.2 330.801 31 344.001C31 344.001 23.4 360.001 25 364.801C25 364.801 41.8 330.001 43 328.401C43 328.401 41 370.802 51.8 334.801C51.8 334.801 57.4 346.801 54.6 351.201C54.6 351.201 62.6 343.201 61.8 340.001C61.8 340.001 66.4 331.801 69.2 345.401C69.2 345.401 71 354.801 72.6 351.601C72.6 351.601 76.6 375.602 77.8 352.801C77.8 352.801 79.4 339.201 72.2 327.601C72.2 327.601 73 324.401 70.2 320.401C70.2 320.401 83.8 342.001 76.6 313.201C76.6 313.201 87.801 321.201 89.001 321.201C89.001 321.201 75.4 298.001 84.2 302.801C84.2 302.801 79 292.401 97.001 304.401C97.001 304.401 81 288.401 98.601 298.001C98.601 298.001 106.601 304.401 99.001 294.401C99.001 294.401 84.6 278.401 106.601 296.401C106.601 296.401 118.201 312.801 119.001 315.601C119.001 315.601 109.001 286.401 104.601 283.601C104.601 283.601 113.001 247.201 154.201 262.801C154.201 262.801 161.001 280.001 165.401 261.601C165.401 261.601 178.201 255.201 189.401 282.801C189.401 282.801 193.401 269.201 192.601 266.401C192.601 266.401 199.401 267.601 198.601 266.401C198.601 266.401 211.801 270.801 213.001 270.001C213.001 270.001 219.801 276.801 220.201 273.201C220.201 273.201 229.401 276.001 227.401 272.401C227.401 272.401 236.201 288.001 236.601 291.601L239.001 277.601L241.001 280.401C241.001 280.401 242.601 272.801 241.801 271.601C241.001 270.401 261.801 278.401 266.601 299.201L268.601 307.601C268.601 307.601 274.601 292.801 273.001 288.801C273.001 288.801 278.201 289.601 278.601 294.001C278.601 294.001 282.601 270.801 277.801 264.801C277.801 264.801 282.201 264.001 283.401 267.601L283.401 260.401C283.401 260.401 290.601 261.201 290.601 258.801C290.601 258.801 295.001 254.801 297.001 259.601C297.001 259.601 284.601 224.401 303.001 243.601C303.001 243.601 310.201 254.401 306.601 235.601C303.001 216.801 299.001 215.201 303.801 214.801C303.801 214.801 304.601 211.201 302.601 209.601C300.601 208.001 303.801 209.601 303.801 209.601C303.801 209.601 308.601 213.601 303.401 191.601C303.401 191.601 309.801 193.201 297.801 164.001C297.801 164.001 300.601 161.601 296.601 153.201C296.601 153.201 304.601 157.601 307.401 156.001C307.401 156.001 307.001 154.401 303.801 150.401C303.801 150.401 282.201 95.6 302.601 117.601C302.601 117.601 314.451 131.151 308.051 108.351C308.051 108.351 298.94 84.341 299.717 80.045L-129.83 103.065z"/>
- </g>
- <g style="fill: #cc7226; stroke:#000000">
- <path d="M299.717 80.245C300.345 80.426 302.551 81.55 303.801 83.2C303.801 83.2 310.601 94 305.401 75.6C305.401 75.6 296.201 46.8 305.001 58C305.001 58 311.001 65.2 307.801 51.6C303.936 35.173 301.401 28.8 301.401 28.8C301.401 28.8 313.001 33.6 286.201 -6L295.001 -2.4C295.001 -2.4 275.401 -42 253.801 -47.2L245.801 -53.2C245.801 -53.2 284.201 -91.2 271.401 -128C271.401 -128 264.601 -133.2 255.001 -124C255.001 -124 248.601 -119.2 242.601 -120.8C242.601 -120.8 211.801 -119.6 209.801 -119.6C207.801 -119.6 173.001 -156.8 107.401 -139.2C107.401 -139.2 102.201 -137.2 97.801 -138.4C97.801 -138.4 79.4 -154.4 30.6 -131.6C30.6 -131.6 20.6 -129.6 19 -129.6C17.4 -129.6 14.6 -129.6 6.6 -123.2C-1.4 -116.8 -1.8 -116 -3.8 -114.4C-3.8 -114.4 -20.2 -103.2 -25 -102.4C-25 -102.4 -36.6 -96 -41 -86L-44.6 -84.8C-44.6 -84.8 -46.2 -77.6 -46.6 -76.4C-46.6 -76.4 -51.4 -72.8 -52.2 -67.2C-52.2 -67.2 -61 -61.2 -60.6 -56.8C-60.6 -56.8 -62.2 -51.6 -63 -46.8C-63 -46.8 -70.2 -42 -69.4 -39.2C-69.4 -39.2 -77 -25.2 -75.8 -18.4C-75.8 -18.4 -82.2 -18.8 -85 -16.4C-85 -16.4 -85.8 -11.6 -87.4 -11.2C-87.4 -11.2 -90.2 -10 -87.8 -6C-87.8 -6 -89.4 -3.2 -89.8 -1.6C-89.8 -1.6 -89 1.2 -93.4 6.8C-93.4 6.8 -99.8 25.6 -97.8 30.8C-97.8 30.8 -97.4 35.6 -100.2 37.2C-100.2 37.2 -103.8 36.8 -95.4 48.8C-95.4 48.8 -94.6 50 -97.8 52.4C-97.8 52.4 -115 56 -117.4 72.4C-117.4 72.4 -131 87.2 -131 92.4C-131 94.705 -130.729 97.852 -130.03 102.465C-130.03 102.465 -130.6 110.801 -103 111.601C-75.4 112.401 299.717 80.245 299.717 80.245z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M-115.6 102.6C-140.6 63.2 -126.2 119.601 -126.2 119.601C-117.4 154.001 12.2 116.401 12.2 116.401C12.2 116.401 181.001 86 192.201 82C203.401 78 298.601 84.4 298.601 84.4L293.001 67.6C228.201 21.2 209.001 44.4 195.401 40.4C181.801 36.4 184.201 46 181.001 46.8C177.801 47.6 138.601 22.8 132.201 23.6C125.801 24.4 100.459 0.649 115.401 32.4C131.401 66.4 57 71.6 40.2 60.4C23.4 49.2 47.4 78.8 47.4 78.8C65.8 98.8 31.4 82 31.4 82C-3 69.2 -27 94.8 -30.2 95.6C-33.4 96.4 -38.2 99.6 -39 93.2C-39.8 86.8 -47.31 70.099 -79 96.4C-99 113.001 -112.8 91 -112.8 91L-115.6 102.6z"/>
- </g>
- <g style="fill: #e87f3a">
- <path d="M133.51 25.346C127.11 26.146 101.743 2.407 116.71 34.146C133.31 69.346 58.31 73.346 41.51 62.146C24.709 50.946 48.71 80.546 48.71 80.546C67.11 100.546 32.709 83.746 32.709 83.746C-1.691 70.946 -25.691 96.546 -28.891 97.346C-32.091 98.146 -36.891 101.346 -37.691 94.946C-38.491 88.546 -45.87 72.012 -77.691 98.146C-98.927 115.492 -112.418 94.037 -112.418 94.037L-115.618 104.146C-140.618 64.346 -125.546 122.655 -125.546 122.655C-116.745 157.056 13.509 118.146 13.509 118.146C13.509 118.146 182.31 87.746 193.51 83.746C204.71 79.746 299.038 86.073 299.038 86.073L293.51 68.764C228.71 22.364 210.31 46.146 196.71 42.146C183.11 38.146 185.51 47.746 182.31 48.546C179.11 49.346 139.91 24.546 133.51 25.346z"/>
- </g>
- <g style="fill: #ea8c4d">
- <path d="M134.819 27.091C128.419 27.891 103.685 3.862 118.019 35.891C134.219 72.092 59.619 75.092 42.819 63.892C26.019 52.692 50.019 82.292 50.019 82.292C68.419 102.292 34.019 85.492 34.019 85.492C-0.381 72.692 -24.382 98.292 -27.582 99.092C-30.782 99.892 -35.582 103.092 -36.382 96.692C-37.182 90.292 -44.43 73.925 -76.382 99.892C-98.855 117.983 -112.036 97.074 -112.036 97.074L-115.636 105.692C-139.436 66.692 -124.891 125.71 -124.891 125.71C-116.091 160.11 14.819 119.892 14.819 119.892C14.819 119.892 183.619 89.492 194.819 85.492C206.019 81.492 299.474 87.746 299.474 87.746L294.02 69.928C229.219 23.528 211.619 47.891 198.019 43.891C184.419 39.891 186.819 49.491 183.619 50.292C180.419 51.092 141.219 26.291 134.819 27.091z"/>
- </g>
- <g style="fill: #ec9961">
- <path d="M136.128 28.837C129.728 29.637 104.999 5.605 119.328 37.637C136.128 75.193 60.394 76.482 44.128 65.637C27.328 54.437 51.328 84.037 51.328 84.037C69.728 104.037 35.328 87.237 35.328 87.237C0.928 74.437 -23.072 100.037 -26.272 100.837C-29.472 101.637 -34.272 104.837 -35.072 98.437C-35.872 92.037 -42.989 75.839 -75.073 101.637C-98.782 120.474 -111.655 100.11 -111.655 100.11L-115.655 107.237C-137.455 70.437 -124.236 128.765 -124.236 128.765C-115.436 163.165 16.128 121.637 16.128 121.637C16.128 121.637 184.928 91.237 196.129 87.237C207.329 83.237 299.911 89.419 299.911 89.419L294.529 71.092C229.729 24.691 212.929 49.637 199.329 45.637C185.728 41.637 188.128 51.237 184.928 52.037C181.728 52.837 142.528 28.037 136.128 28.837z"/>
- </g>
- <g style="fill: #eea575">
- <path d="M137.438 30.583C131.037 31.383 106.814 7.129 120.637 39.383C137.438 78.583 62.237 78.583 45.437 67.383C28.637 56.183 52.637 85.783 52.637 85.783C71.037 105.783 36.637 88.983 36.637 88.983C2.237 76.183 -21.763 101.783 -24.963 102.583C-28.163 103.383 -32.963 106.583 -33.763 100.183C-34.563 93.783 -41.548 77.752 -73.763 103.383C-98.709 122.965 -111.273 103.146 -111.273 103.146L-115.673 108.783C-135.473 73.982 -123.582 131.819 -123.582 131.819C-114.782 166.22 17.437 123.383 17.437 123.383C17.437 123.383 186.238 92.983 197.438 88.983C208.638 84.983 300.347 91.092 300.347 91.092L295.038 72.255C230.238 25.855 214.238 51.383 200.638 47.383C187.038 43.383 189.438 52.983 186.238 53.783C183.038 54.583 143.838 29.783 137.438 30.583z"/>
- </g>
- <g style="fill: #f1b288">
- <path d="M138.747 32.328C132.347 33.128 106.383 9.677 121.947 41.128C141.147 79.928 63.546 80.328 46.746 69.128C29.946 57.928 53.946 87.528 53.946 87.528C72.346 107.528 37.946 90.728 37.946 90.728C3.546 77.928 -20.454 103.528 -23.654 104.328C-26.854 105.128 -31.654 108.328 -32.454 101.928C-33.254 95.528 -40.108 79.665 -72.454 105.128C-98.636 125.456 -110.891 106.183 -110.891 106.183L-115.691 110.328C-133.691 77.128 -122.927 134.874 -122.927 134.874C-114.127 169.274 18.746 125.128 18.746 125.128C18.746 125.128 187.547 94.728 198.747 90.728C209.947 86.728 300.783 92.764 300.783 92.764L295.547 73.419C230.747 27.019 215.547 53.128 201.947 49.128C188.347 45.128 190.747 54.728 187.547 55.528C184.347 56.328 145.147 31.528 138.747 32.328z"/>
- </g>
- <g style="fill: #f3bf9c">
- <path d="M140.056 34.073C133.655 34.873 107.313 11.613 123.255 42.873C143.656 82.874 64.855 82.074 48.055 70.874C31.255 59.674 55.255 89.274 55.255 89.274C73.655 109.274 39.255 92.474 39.255 92.474C4.855 79.674 -19.145 105.274 -22.345 106.074C-25.545 106.874 -30.345 110.074 -31.145 103.674C-31.945 97.274 -38.668 81.578 -71.145 106.874C-98.564 127.947 -110.509 109.219 -110.509 109.219L-115.709 111.874C-131.709 81.674 -122.273 137.929 -122.273 137.929C-113.473 172.329 20.055 126.874 20.055 126.874C20.055 126.874 188.856 96.474 200.056 92.474C211.256 88.474 301.22 94.437 301.22 94.437L296.056 74.583C231.256 28.183 216.856 54.874 203.256 50.874C189.656 46.873 192.056 56.474 188.856 57.274C185.656 58.074 146.456 33.273 140.056 34.073z"/>
- </g>
- <g style="fill: #f5ccb0">
- <path d="M141.365 35.819C134.965 36.619 107.523 13.944 124.565 44.619C146.565 84.219 66.164 83.819 49.364 72.619C32.564 61.419 56.564 91.019 56.564 91.019C74.964 111.019 40.564 94.219 40.564 94.219C6.164 81.419 -17.836 107.019 -21.036 107.819C-24.236 108.619 -29.036 111.819 -29.836 105.419C-30.636 99.019 -37.227 83.492 -69.836 108.619C-98.491 130.438 -110.127 112.256 -110.127 112.256L-115.727 113.419C-130.128 85.019 -121.618 140.983 -121.618 140.983C-112.818 175.384 21.364 128.619 21.364 128.619C21.364 128.619 190.165 98.219 201.365 94.219C212.565 90.219 301.656 96.11 301.656 96.11L296.565 75.746C231.765 29.346 218.165 56.619 204.565 52.619C190.965 48.619 193.365 58.219 190.165 59.019C186.965 59.819 147.765 35.019 141.365 35.819z"/>
- </g>
- <g style="fill: #f8d8c4">
- <path d="M142.674 37.565C136.274 38.365 108.832 15.689 125.874 46.365C147.874 85.965 67.474 85.565 50.674 74.365C33.874 63.165 57.874 92.765 57.874 92.765C76.274 112.765 41.874 95.965 41.874 95.965C7.473 83.165 -16.527 108.765 -19.727 109.565C-22.927 110.365 -27.727 113.565 -28.527 107.165C-29.327 100.765 -35.786 85.405 -68.527 110.365C-98.418 132.929 -109.745 115.293 -109.745 115.293L-115.745 114.965C-129.346 88.564 -120.963 144.038 -120.963 144.038C-112.163 178.438 22.673 130.365 22.673 130.365C22.673 130.365 191.474 99.965 202.674 95.965C213.874 91.965 302.093 97.783 302.093 97.783L297.075 76.91C232.274 30.51 219.474 58.365 205.874 54.365C192.274 50.365 194.674 59.965 191.474 60.765C188.274 61.565 149.074 36.765 142.674 37.565z"/>
- </g>
- <g style="fill: #fae5d7">
- <path d="M143.983 39.31C137.583 40.11 110.529 17.223 127.183 48.11C149.183 88.91 68.783 87.31 51.983 76.11C35.183 64.91 59.183 94.51 59.183 94.51C77.583 114.51 43.183 97.71 43.183 97.71C8.783 84.91 -15.217 110.51 -18.417 111.31C-21.618 112.11 -26.418 115.31 -27.218 108.91C-28.018 102.51 -34.346 87.318 -67.218 112.11C-98.345 135.42 -109.363 118.329 -109.363 118.329L-115.764 116.51C-128.764 92.51 -120.309 147.093 -120.309 147.093C-111.509 181.493 23.983 132.11 23.983 132.11C23.983 132.11 192.783 101.71 203.983 97.71C215.183 93.71 302.529 99.456 302.529 99.456L297.583 78.074C232.783 31.673 220.783 60.11 207.183 56.11C193.583 52.11 195.983 61.71 192.783 62.51C189.583 63.31 150.383 38.51 143.983 39.31z"/>
- </g>
- <g style="fill: #fcf2eb">
- <path d="M145.292 41.055C138.892 41.855 112.917 18.411 128.492 49.855C149.692 92.656 70.092 89.056 53.292 77.856C36.492 66.656 60.492 96.256 60.492 96.256C78.892 116.256 44.492 99.456 44.492 99.456C10.092 86.656 -13.908 112.256 -17.108 113.056C-20.308 113.856 -25.108 117.056 -25.908 110.656C-26.708 104.256 -32.905 89.232 -65.908 113.856C-98.273 137.911 -108.982 121.365 -108.982 121.365L-115.782 118.056C-128.582 94.856 -119.654 150.147 -119.654 150.147C-110.854 184.547 25.292 133.856 25.292 133.856C25.292 133.856 194.093 103.456 205.293 99.456C216.493 95.456 302.965 101.128 302.965 101.128L298.093 79.237C233.292 32.837 222.093 61.856 208.493 57.856C194.893 53.855 197.293 63.456 194.093 64.256C190.892 65.056 151.692 40.255 145.292 41.055z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M-115.8 119.601C-128.6 97.6 -119 153.201 -119 153.201C-110.2 187.601 26.6 135.601 26.6 135.601C26.6 135.601 195.401 105.2 206.601 101.2C217.801 97.2 303.401 102.8 303.401 102.8L298.601 80.4C233.801 34 223.401 63.6 209.801 59.6C196.201 55.6 198.601 65.2 195.401 66C192.201 66.8 153.001 42 146.601 42.8C140.201 43.6 114.981 19.793 129.801 51.6C152.028 99.307 69.041 89.227 54.6 79.6C37.8 68.4 61.8 98 61.8 98C80.2 118.001 45.8 101.2 45.8 101.2C11.4 88.4 -12.6 114.001 -15.8 114.801C-19 115.601 -23.8 118.801 -24.6 112.401C-25.4 106 -31.465 91.144 -64.6 115.601C-98.2 140.401 -108.6 124.401 -108.6 124.401L-115.8 119.601z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-74.2 149.601C-74.2 149.601 -81.4 161.201 -60.6 174.401C-60.6 174.401 -59.2 175.801 -77.2 171.601C-77.2 171.601 -83.4 169.601 -85 159.201C-85 159.201 -89.8 154.801 -94.6 149.201C-99.4 143.601 -74.2 149.601 -74.2 149.601z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M65.8 102C65.8 102 83.498 128.821 82.9 133.601C81.6 144.001 81.4 153.601 84.6 157.601C87.801 161.601 96.601 194.801 96.601 194.801C96.601 194.801 96.201 196.001 108.601 158.001C108.601 158.001 120.201 142.001 100.201 123.601C100.201 123.601 65 94.8 65.8 102z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-54.2 176.401C-54.2 176.401 -43 183.601 -57.4 214.801L-51 212.401C-51 212.401 -51.8 223.601 -55 226.001L-47.8 222.801C-47.8 222.801 -43 230.801 -47 235.601C-47 235.601 -30.2 243.601 -31 250.001C-31 250.001 -24.6 242.001 -28.6 235.601C-32.6 229.201 -39.8 233.201 -39 214.801L-47.8 218.001C-47.8 218.001 -42.2 209.201 -42.2 202.801L-50.2 205.201C-50.2 205.201 -34.731 178.623 -45.4 177.201C-51.4 176.401 -54.2 176.401 -54.2 176.401z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-21.8 193.201C-21.8 193.201 -19 188.801 -21.8 189.601C-24.6 190.401 -55.8 205.201 -61.8 214.801C-61.8 214.801 -27.4 190.401 -21.8 193.201z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-11.4 201.201C-11.4 201.201 -8.6 196.801 -11.4 197.601C-14.2 198.401 -45.4 213.201 -51.4 222.801C-51.4 222.801 -17 198.401 -11.4 201.201z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M1.8 186.001C1.8 186.001 4.6 181.601 1.8 182.401C-1 183.201 -32.2 198.001 -38.2 207.601C-38.2 207.601 -3.8 183.201 1.8 186.001z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-21.4 229.601C-21.4 229.601 -21.4 223.601 -24.2 224.401C-27 225.201 -63 242.801 -69 252.401C-69 252.401 -27 226.801 -21.4 229.601z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-20.2 218.801C-20.2 218.801 -19 214.001 -21.8 214.801C-23.8 214.801 -50.2 226.401 -56.2 236.001C-56.2 236.001 -26.6 214.401 -20.2 218.801z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-34.6 266.401L-44.6 274.001C-44.6 274.001 -34.2 266.401 -30.6 267.601C-30.6 267.601 -37.4 278.801 -38.2 284.001C-38.2 284.001 -27.8 271.201 -22.2 271.601C-22.2 271.601 -14.6 272.001 -14.6 282.801C-14.6 282.801 -9 272.401 -5.8 272.801C-5.8 272.801 -4.6 279.201 -5.8 286.001C-5.8 286.001 -1.8 278.401 2.2 280.001C2.2 280.001 8.6 278.001 7.8 289.601C7.8 289.601 7.8 300.001 7 302.801C7 302.801 12.6 276.401 15 276.001C15 276.001 23 274.801 27.8 283.601C27.8 283.601 23.8 276.001 28.6 278.001C28.6 278.001 39.4 279.601 42.6 286.401C42.6 286.401 35.8 274.401 41.4 277.601C41.4 277.601 48.2 277.601 49.4 284.001C49.4 284.001 57.8 305.201 59.8 306.801C59.8 306.801 52.2 285.201 53.8 285.201C53.8 285.201 51.8 273.201 57 288.001C57 288.001 53.8 274.001 59.4 274.801C65 275.601 69.4 285.601 77.8 283.201C77.8 283.201 87.401 288.801 89.401 219.601L-34.6 266.401z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-29.8 173.601C-29.8 173.601 -15 167.601 25 173.601C25 173.601 32.2 174.001 39 165.201C45.8 156.401 72.6 149.201 79 151.201L88.601 157.601L89.401 158.801C89.401 158.801 101.801 169.201 102.201 176.801C102.601 184.401 87.801 232.401 78.2 248.401C68.6 264.401 59 276.801 39.8 274.401C39.8 274.401 19 270.401 -6.6 274.401C-6.6 274.401 -35.8 272.801 -38.6 264.801C-41.4 256.801 -27.4 241.601 -27.4 241.601C-27.4 241.601 -23 233.201 -24.2 218.801C-25.4 204.401 -25 176.401 -29.8 173.601z"/>
- </g>
- <g style="fill: #e5668c">
- <path d="M-7.8 175.601C0.6 194.001 -29 259.201 -29 259.201C-31 260.801 -16.34 266.846 -6.2 264.401C4.746 261.763 45 266.001 45 266.001C68.6 250.401 81.4 206.001 81.4 206.001C81.4 206.001 91.801 182.001 74.2 178.801C56.6 175.601 -7.8 175.601 -7.8 175.601z"/>
- </g>
- <g style="fill: #b23259">
- <path d="M-9.831 206.497C-6.505 193.707 -4.921 181.906 -7.8 175.601C-7.8 175.601 54.6 182.001 65.8 161.201C70.041 153.326 84.801 184.001 84.4 193.601C84.4 193.601 21.4 208.001 6.6 196.801L-9.831 206.497z"/>
- </g>
- <g style="fill: #a5264c">
- <path d="M-5.4 222.801C-5.4 222.801 -3.4 230.001 -5.8 234.001C-5.8 234.001 -7.4 234.801 -8.6 235.201C-8.6 235.201 -7.4 238.801 -1.4 240.401C-1.4 240.401 0.6 244.801 3 245.201C5.4 245.601 10.2 251.201 14.2 250.001C18.2 248.801 29.4 244.801 29.4 244.801C29.4 244.801 35 241.601 43.8 245.201C43.8 245.201 46.175 244.399 46.6 240.401C47.1 235.701 50.2 232.001 52.2 230.001C54.2 228.001 63.8 215.201 62.6 214.801C61.4 214.401 -5.4 222.801 -5.4 222.801z"/>
- </g>
- <g style="fill: #ff727f; stroke:#000000">
- <path d="M-9.8 174.401C-9.8 174.401 -12.6 196.801 -9.4 205.201C-6.2 213.601 -7 215.601 -7.8 219.601C-8.6 223.601 -4.2 233.601 1.4 239.601L13.4 241.201C13.4 241.201 28.6 237.601 37.8 240.401C37.8 240.401 46.794 241.744 50.2 226.801C50.2 226.801 55 220.401 62.2 217.601C69.4 214.801 76.6 173.201 72.6 165.201C68.6 157.201 54.2 152.801 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-8.2 249.201C-8.2 249.201 -9 247.201 -13.4 246.801C-13.4 246.801 -35.8 243.201 -44.2 230.801C-44.2 230.801 -51 225.201 -46.6 236.801C-46.6 236.801 -36.2 257.201 -29.4 260.001C-29.4 260.001 -13 264.001 -8.2 249.201z"/>
- </g>
- <g style="fill: #cc3f4c">
- <path d="M71.742 185.229C72.401 177.323 74.354 168.709 72.6 165.201C66.154 152.307 49.181 157.695 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401C-9.8 174.401 -11.545 188.364 -10.705 198.376C-10.705 198.376 26.6 186.801 27.4 192.401C27.4 192.401 29 189.201 38.2 189.201C47.4 189.201 70.142 188.029 71.742 185.229z"/>
- </g>
- <g style="stroke:#a51926; stroke-width:2">
- <path d="M28.6 175.201C28.6 175.201 33.4 180.001 29.8 189.601C29.8 189.601 15.4 205.601 17.4 219.601"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-19.4 260.001C-19.4 260.001 -23.8 247.201 -15 254.001C-15 254.001 -10.2 256.001 -11.4 257.601C-12.6 259.201 -18.2 263.201 -19.4 260.001z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-14.36 261.201C-14.36 261.201 -17.88 250.961 -10.84 256.401C-10.84 256.401 -6.419 258.849 -7.96 259.281C-12.52 260.561 -7.96 263.121 -14.36 261.201z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-9.56 261.201C-9.56 261.201 -13.08 250.961 -6.04 256.401C-6.04 256.401 -1.665 258.711 -3.16 259.281C-6.52 260.561 -3.16 263.121 -9.56 261.201z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-2.96 261.401C-2.96 261.401 -6.48 251.161 0.56 256.601C0.56 256.601 4.943 258.933 3.441 259.481C0.48 260.561 3.441 263.321 -2.96 261.401z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M3.52 261.321C3.52 261.321 0 251.081 7.041 256.521C7.041 256.521 10.881 258.121 9.921 259.401C8.961 260.681 9.921 263.241 3.52 261.321z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M10.2 262.001C10.2 262.001 5.4 249.601 14.6 256.001C14.6 256.001 19.4 258.001 18.2 259.601C17 261.201 18.2 264.401 10.2 262.001z"/>
- </g>
- <g style="stroke:#a5264c; stroke-width:2">
- <path d="M-18.2 244.801C-18.2 244.801 -5 242.001 1 245.201C1 245.201 7 246.401 8.2 246.001C9.4 245.601 12.6 245.201 12.6 245.201"/>
- </g>
- <g style="stroke:#a5264c; stroke-width:2">
- <path d="M15.8 253.601C15.8 253.601 27.8 240.001 39.8 244.401C46.816 246.974 45.8 243.601 46.6 240.801C47.4 238.001 47.6 233.801 52.6 230.801"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M33 237.601C33 237.601 29 226.801 26.2 239.601C23.4 252.401 20.2 256.001 18.6 258.801C18.6 258.801 18.6 264.001 27 263.601C27 263.601 37.8 263.201 38.2 260.401C38.6 257.601 37 246.001 33 237.601z"/>
- </g>
- <g style="stroke:#a5264c; stroke-width:2">
- <path d="M47 244.801C47 244.801 50.6 242.401 53 243.601"/>
- </g>
- <g style="stroke:#a5264c; stroke-width:2">
- <path d="M53.5 228.401C53.5 228.401 56.4 223.501 61.2 222.701"/>
- </g>
- <g style="fill: #b2b2b2">
- <path d="M-25.8 265.201C-25.8 265.201 -7.8 268.401 -3.4 266.801C-3.4 266.801 5.4 266.801 -3 268.801C-3 268.801 -15.8 268.801 -23.8 267.601C-23.8 267.601 -35.4 262.001 -25.8 265.201z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-11.8 172.001C-11.8 172.001 5.8 172.001 7.8 172.801C7.8 172.801 15 203.601 11.4 211.201C11.4 211.201 10.2 214.001 7.4 208.401C7.4 208.401 -11 175.601 -14.2 173.601C-17.4 171.601 -13 172.001 -11.8 172.001z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-88.9 169.301C-88.9 169.301 -80 171.001 -67.4 173.601C-67.4 173.601 -62.6 196.001 -59.4 200.801C-56.2 205.601 -59.8 205.601 -63.4 202.801C-67 200.001 -81.8 186.001 -83.8 181.601C-85.8 177.201 -88.9 169.301 -88.9 169.301z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-67.039 173.818C-67.039 173.818 -61.239 175.366 -60.23 177.581C-59.222 179.795 -61.432 183.092 -61.432 183.092C-61.432 183.092 -62.432 186.397 -63.634 184.235C-64.836 182.072 -67.708 174.412 -67.039 173.818z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-67 173.601C-67 173.601 -63.4 178.801 -59.8 178.801C-56.2 178.801 -55.818 178.388 -53 179.001C-48.4 180.001 -48.8 178.001 -42.2 179.201C-39.56 179.681 -37 178.801 -34.2 180.001C-31.4 181.201 -28.2 180.401 -27 178.401C-25.8 176.401 -21 172.201 -21 172.201C-21 172.201 -33.8 174.001 -36.6 174.801C-36.6 174.801 -59 176.001 -67 173.601z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-22.4 173.801C-22.4 173.801 -28.85 177.301 -29.25 179.701C-29.65 182.101 -24 185.801 -24 185.801C-24 185.801 -21.25 190.401 -20.65 188.001C-20.05 185.601 -21.6 174.201 -22.4 173.801z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-59.885 179.265C-59.885 179.265 -52.878 190.453 -52.661 179.242C-52.661 179.242 -52.104 177.984 -53.864 177.962C-59.939 177.886 -58.418 173.784 -59.885 179.265z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-52.707 179.514C-52.707 179.514 -44.786 190.701 -45.422 179.421C-45.422 179.421 -45.415 179.089 -47.168 178.936C-51.915 178.522 -51.57 174.004 -52.707 179.514z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-45.494 179.522C-45.494 179.522 -37.534 190.15 -38.203 180.484C-38.203 180.484 -38.084 179.251 -39.738 178.95C-43.63 178.244 -43.841 174.995 -45.494 179.522z"/>
- </g>
- <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
- <path d="M-38.618 179.602C-38.618 179.602 -30.718 191.163 -30.37 181.382C-30.37 181.382 -28.726 180.004 -30.472 179.782C-36.29 179.042 -35.492 174.588 -38.618 179.602z"/>
- </g>
- <g style="fill: #e5e5b2">
- <path d="M-74.792 183.132L-82.45 181.601C-85.05 176.601 -87.15 170.451 -87.15 170.451C-87.15 170.451 -80.8 171.451 -68.3 174.251C-68.3 174.251 -67.424 177.569 -65.952 183.364L-74.792 183.132z"/>
- </g>
- <g style="fill: #e5e5b2">
- <path d="M-9.724 178.47C-11.39 175.964 -12.707 174.206 -13.357 173.8C-16.37 171.917 -12.227 172.294 -11.098 172.294C-11.098 172.294 5.473 172.294 7.356 173.047C7.356 173.047 7.88 175.289 8.564 178.68C8.564 178.68 -1.524 176.67 -9.724 178.47z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M43.88 40.321C71.601 44.281 97.121 8.641 98.881 -1.04C100.641 -10.72 90.521 -22.6 90.521 -22.6C91.841 -25.68 87.001 -39.76 81.721 -49C76.441 -58.24 60.54 -57.266 43 -58.24C27.16 -59.12 8.68 -35.8 7.36 -34.04C6.04 -32.28 12.2 6.001 13.52 11.721C14.84 17.441 12.2 43.841 12.2 43.841C46.44 34.741 16.16 36.361 43.88 40.321z"/>
- </g>
- <g style="fill: #ea8e51">
- <path d="M8.088 -33.392C6.792 -31.664 12.84 5.921 14.136 11.537C15.432 17.153 12.84 43.073 12.84 43.073C45.512 34.193 16.728 35.729 43.944 39.617C71.161 43.505 96.217 8.513 97.945 -0.992C99.673 -10.496 89.737 -22.16 89.737 -22.16C91.033 -25.184 86.281 -39.008 81.097 -48.08C75.913 -57.152 60.302 -56.195 43.08 -57.152C27.528 -58.016 9.384 -35.12 8.088 -33.392z"/>
- </g>
- <g style="fill: #efaa7c">
- <path d="M8.816 -32.744C7.544 -31.048 13.48 5.841 14.752 11.353C16.024 16.865 13.48 42.305 13.48 42.305C44.884 33.145 17.296 35.097 44.008 38.913C70.721 42.729 95.313 8.385 97.009 -0.944C98.705 -10.272 88.953 -21.72 88.953 -21.72C90.225 -24.688 85.561 -38.256 80.473 -47.16C75.385 -56.064 60.063 -55.125 43.16 -56.064C27.896 -56.912 10.088 -34.44 8.816 -32.744z"/>
- </g>
- <g style="fill: #f4c6a8">
- <path d="M9.544 -32.096C8.296 -30.432 14.12 5.761 15.368 11.169C16.616 16.577 14.12 41.537 14.12 41.537C43.556 32.497 17.864 34.465 44.072 38.209C70.281 41.953 94.409 8.257 96.073 -0.895C97.737 -10.048 88.169 -21.28 88.169 -21.28C89.417 -24.192 84.841 -37.504 79.849 -46.24C74.857 -54.976 59.824 -54.055 43.24 -54.976C28.264 -55.808 10.792 -33.76 9.544 -32.096z"/>
- </g>
- <g style="fill: #f9e2d3">
- <path d="M10.272 -31.448C9.048 -29.816 14.76 5.681 15.984 10.985C17.208 16.289 14.76 40.769 14.76 40.769C42.628 31.849 18.432 33.833 44.136 37.505C69.841 41.177 93.505 8.129 95.137 -0.848C96.769 -9.824 87.385 -20.84 87.385 -20.84C88.609 -23.696 84.121 -36.752 79.225 -45.32C74.329 -53.888 59.585 -52.985 43.32 -53.888C28.632 -54.704 11.496 -33.08 10.272 -31.448z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M44.2 36.8C69.4 40.4 92.601 8 94.201 -0.8C95.801 -9.6 86.601 -20.4 86.601 -20.4C87.801 -23.2 83.4 -36 78.6 -44.4C73.8 -52.8 59.346 -51.914 43.4 -52.8C29 -53.6 12.2 -32.4 11 -30.8C9.8 -29.2 15.4 5.6 16.6 10.8C17.8 16 15.4 40 15.4 40C40.9 31.4 19 33.2 44.2 36.8z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M90.601 2.8C90.601 2.8 62.8 10.4 51.2 8.8C51.2 8.8 35.4 2.2 26.6 24C26.6 24 23 31.2 21 33.2C19 35.2 90.601 2.8 90.601 2.8z"/>
- </g>
- <g style="fill: #000000">
- <path d="M94.401 0.6C94.401 0.6 65.4 12.8 55.4 12.4C55.4 12.4 39 7.8 30.6 22.4C30.6 22.4 22.2 31.6 19 33.2C19 33.2 18.6 34.8 25 30.8L35.4 36C35.4 36 50.2 45.6 59.8 29.6C59.8 29.6 63.8 18.4 63.8 16.4C63.8 14.4 85 8.8 86.601 8.4C88.201 8 94.801 3.8 94.401 0.6z"/>
- </g>
- <g style="fill: #99cc32">
- <path d="M47 36.514C40.128 36.514 31.755 32.649 31.755 26.4C31.755 20.152 40.128 13.887 47 13.887C53.874 13.887 59.446 18.952 59.446 25.2C59.446 31.449 53.874 36.514 47 36.514z"/>
- </g>
- <g style="fill: #659900">
- <path d="M43.377 19.83C38.531 20.552 33.442 22.055 33.514 21.839C35.054 17.22 41.415 13.887 47 13.887C51.296 13.887 55.084 15.865 57.32 18.875C57.32 18.875 52.004 18.545 43.377 19.83z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M55.4 19.6C55.4 19.6 51 16.4 51 18.6C51 18.6 54.6 23 55.4 19.6z"/>
- </g>
- <g style="fill: #000000">
- <path d="M45.4 27.726C42.901 27.726 40.875 25.7 40.875 23.2C40.875 20.701 42.901 18.675 45.4 18.675C47.9 18.675 49.926 20.701 49.926 23.2C49.926 25.7 47.9 27.726 45.4 27.726z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M-58.6 14.4C-58.6 14.4 -61.8 -6.8 -59.4 -11.2C-59.4 -11.2 -48.6 -21.2 -49 -24.8C-49 -24.8 -49.4 -42.8 -50.6 -43.6C-51.8 -44.4 -59.4 -50.4 -65.4 -44C-65.4 -44 -75.8 -26 -75 -19.6L-75 -17.6C-75 -17.6 -82.6 -18 -84.2 -16C-84.2 -16 -85.4 -10.8 -86.6 -10.4C-86.6 -10.4 -89.4 -8 -87.4 -5.2C-87.4 -5.2 -89.4 -2.8 -89 1.2L-81.4 5.2C-81.4 5.2 -79.4 19.6 -68.6 24.8C-63.764 27.129 -60.6 20.4 -58.6 14.4z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M-59.6 12.56C-59.6 12.56 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.48 -40.36 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.96 -59.6 12.56z"/>
- </g>
- <g style="fill: #eb955c">
- <path d="M-51.05 -42.61C-52.14 -43.47 -59.63 -49.24 -65.48 -43C-65.48 -43 -75.62 -25.45 -74.84 -19.21L-74.84 -17.26C-74.84 -17.26 -82.25 -17.65 -83.81 -15.7C-83.81 -15.7 -84.98 -10.63 -86.15 -10.24C-86.15 -10.24 -88.88 -7.9 -86.93 -5.17C-86.93 -5.17 -88.88 -2.83 -88.49 1.07L-81.08 4.97C-81.08 4.97 -79.13 19.01 -68.6 24.08C-63.886 26.35 -60.8 19.79 -58.85 13.94C-58.85 13.94 -61.97 -6.73 -59.63 -11.02C-59.63 -11.02 -49.1 -20.77 -49.49 -24.28C-49.49 -24.28 -49.88 -41.83 -51.05 -42.61z"/>
- </g>
- <g style="fill: #f2b892">
- <path d="M-51.5 -41.62C-52.48 -42.54 -59.86 -48.08 -65.56 -42C-65.56 -42 -75.44 -24.9 -74.68 -18.82L-74.68 -16.92C-74.68 -16.92 -81.9 -17.3 -83.42 -15.4C-83.42 -15.4 -84.56 -10.46 -85.7 -10.08C-85.7 -10.08 -88.36 -7.8 -86.46 -5.14C-86.46 -5.14 -88.36 -2.86 -87.98 0.94L-80.76 4.74C-80.76 4.74 -78.86 18.42 -68.6 23.36C-64.006 25.572 -61 19.18 -59.1 13.48C-59.1 13.48 -62.14 -6.66 -59.86 -10.84C-59.86 -10.84 -49.6 -20.34 -49.98 -23.76C-49.98 -23.76 -50.36 -40.86 -51.5 -41.62z"/>
- </g>
- <g style="fill: #f8dcc8">
- <path d="M-51.95 -40.63C-52.82 -41.61 -60.09 -46.92 -65.64 -41C-65.64 -41 -75.26 -24.35 -74.52 -18.43L-74.52 -16.58C-74.52 -16.58 -81.55 -16.95 -83.03 -15.1C-83.03 -15.1 -84.14 -10.29 -85.25 -9.92C-85.25 -9.92 -87.84 -7.7 -85.99 -5.11C-85.99 -5.11 -87.84 -2.89 -87.47 0.81L-80.44 4.51C-80.44 4.51 -78.59 17.83 -68.6 22.64C-64.127 24.794 -61.2 18.57 -59.35 13.02C-59.35 13.02 -62.31 -6.59 -60.09 -10.66C-60.09 -10.66 -50.1 -19.91 -50.47 -23.24C-50.47 -23.24 -50.84 -39.89 -51.95 -40.63z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M-59.6 12.46C-59.6 12.46 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.16 -40.68 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.86 -59.6 12.46z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-62.7 6.2C-62.7 6.2 -84.3 -4 -85.2 -4.8C-85.2 -4.8 -76.1 3.4 -75.3 3.4C-74.5 3.4 -62.7 6.2 -62.7 6.2z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-79.8 0C-79.8 0 -61.4 3.6 -61.4 8C-61.4 10.912 -61.643 24.331 -67 22.8C-75.4 20.4 -71.8 6 -79.8 0z"/>
- </g>
- <g style="fill: #99cc32">
- <path d="M-71.4 3.8C-71.4 3.8 -62.422 5.274 -61.4 8C-60.8 9.6 -60.137 17.908 -65.6 19C-70.152 19.911 -72.382 9.69 -71.4 3.8z"/>
- </g>
- <g style="fill: #000000">
- <path d="M14.595 46.349C14.098 44.607 15.409 44.738 17.2 44.2C19.2 43.6 31.4 39.8 32.2 37.2C33 34.6 46.2 39 46.2 39C48 39.8 52.4 42.4 52.4 42.4C57.2 43.6 63.8 44 63.8 44C66.2 45 69.6 47.8 69.6 47.8C84.2 58 96.601 50.8 96.601 50.8C116.601 44.2 110.601 27 110.601 27C107.601 18 110.801 14.6 110.801 14.6C111.001 10.8 118.201 17.2 118.201 17.2C120.801 21.4 121.601 26.4 121.601 26.4C129.601 37.6 126.201 19.8 126.201 19.8C126.401 18.8 123.601 15.2 123.601 14C123.601 12.8 121.801 9.4 121.801 9.4C118.801 6 121.201 -1 121.201 -1C123.001 -14.8 120.801 -13 120.801 -13C119.601 -14.8 110.401 -4.8 110.401 -4.8C108.201 -1.4 102.201 0.2 102.201 0.2C99.401 2 96.001 0.6 96.001 0.6C93.401 0.2 87.801 7.2 87.801 7.2C90.601 7 93.001 11.4 95.401 11.6C97.801 11.8 99.601 9.2 101.201 8.6C102.801 8 105.601 13.8 105.601 13.8C106.001 16.4 100.401 21.2 100.401 21.2C100.001 25.8 98.401 24.2 98.401 24.2C95.401 23.6 94.201 27.4 93.201 32C92.201 36.6 88.001 37 88.001 37C86.401 44.4 85.2 41.4 85.2 41.4C85 35.8 79 41.6 79 41.6C77.8 43.6 73.2 41.4 73.2 41.4C66.4 39.4 68.8 37.4 68.8 37.4C70.6 35.2 81.8 37.4 81.8 37.4C84 35.8 76 31.8 76 31.8C75.4 30 76.4 25.6 76.4 25.6C77.6 22.4 84.4 16.8 84.4 16.8C93.801 15.6 91.001 14 91.001 14C84.801 8.8 79 16.4 79 16.4C76.8 22.6 59.4 37.6 59.4 37.6C54.6 41 57.2 34.2 53.2 37.6C49.2 41 28.6 32 28.6 32C17.038 30.807 14.306 46.549 10.777 43.429C10.777 43.429 16.195 51.949 14.595 46.349z"/>
- </g>
- <g style="fill: #000000">
- <path d="M209.401 -120C209.401 -120 183.801 -112 181.001 -93.2C181.001 -93.2 178.601 -70.4 199.001 -52.8C199.001 -52.8 199.401 -46.4 201.401 -43.2C201.401 -43.2 199.801 -38.4 218.601 -46L245.801 -54.4C245.801 -54.4 252.201 -56.8 257.401 -65.6C262.601 -74.4 277.801 -93.2 274.201 -118.4C274.201 -118.4 275.401 -129.6 269.401 -130C269.401 -130 261.001 -131.6 253.801 -124C253.801 -124 247.001 -120.8 244.601 -121.2L209.401 -120z"/>
- </g>
- <g style="fill: #000000">
- <path d="M264.022 -120.99C264.022 -120.99 266.122 -129.92 261.282 -125.08C261.282 -125.08 254.242 -119.36 246.761 -119.36C246.761 -119.36 232.241 -117.16 227.841 -103.96C227.841 -103.96 223.881 -77.12 231.801 -71.4C231.801 -71.4 236.641 -63.92 243.681 -70.52C250.722 -77.12 266.222 -107.35 264.022 -120.99z"/>
- </g>
- <g style="fill: #323232">
- <path d="M263.648 -120.632C263.648 -120.632 265.738 -129.376 260.986 -124.624C260.986 -124.624 254.074 -119.008 246.729 -119.008C246.729 -119.008 232.473 -116.848 228.153 -103.888C228.153 -103.888 224.265 -77.536 232.041 -71.92C232.041 -71.92 236.793 -64.576 243.705 -71.056C250.618 -77.536 265.808 -107.24 263.648 -120.632z"/>
- </g>
- <g style="fill: #666666">
- <path d="M263.274 -120.274C263.274 -120.274 265.354 -128.832 260.69 -124.168C260.69 -124.168 253.906 -118.656 246.697 -118.656C246.697 -118.656 232.705 -116.536 228.465 -103.816C228.465 -103.816 224.649 -77.952 232.281 -72.44C232.281 -72.44 236.945 -65.232 243.729 -71.592C250.514 -77.952 265.394 -107.13 263.274 -120.274z"/>
- </g>
- <g style="fill: #999999">
- <path d="M262.9 -119.916C262.9 -119.916 264.97 -128.288 260.394 -123.712C260.394 -123.712 253.738 -118.304 246.665 -118.304C246.665 -118.304 232.937 -116.224 228.777 -103.744C228.777 -103.744 225.033 -78.368 232.521 -72.96C232.521 -72.96 237.097 -65.888 243.753 -72.128C250.41 -78.368 264.98 -107.02 262.9 -119.916z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M262.526 -119.558C262.526 -119.558 264.586 -127.744 260.098 -123.256C260.098 -123.256 253.569 -117.952 246.633 -117.952C246.633 -117.952 233.169 -115.912 229.089 -103.672C229.089 -103.672 225.417 -78.784 232.761 -73.48C232.761 -73.48 237.249 -66.544 243.777 -72.664C250.305 -78.784 264.566 -106.91 262.526 -119.558z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M262.151 -119.2C262.151 -119.2 264.201 -127.2 259.801 -122.8C259.801 -122.8 253.401 -117.6 246.601 -117.6C246.601 -117.6 233.401 -115.6 229.401 -103.6C229.401 -103.6 225.801 -79.2 233.001 -74C233.001 -74 237.401 -67.2 243.801 -73.2C250.201 -79.2 264.151 -106.8 262.151 -119.2z"/>
- </g>
- <g style="fill: #992600">
- <path d="M50.6 84C50.6 84 30.2 64.8 22.2 64C22.2 64 -12.2 60 -27 78C-27 78 -9.4 57.6 18.2 63.2C18.2 63.2 -3.4 58.8 -15.8 62C-15.8 62 -32.6 62 -42.2 76L-45 80.8C-45 80.8 -41 66 -22.6 60C-22.6 60 0.2 55.2 11 60C11 60 -10.6 53.2 -20.6 55.2C-20.6 55.2 -51 52.8 -63.8 79.2C-63.8 79.2 -59.8 64.8 -45 57.6C-45 57.6 -31.4 48.8 -11 51.6C-11 51.6 3.4 54.8 8.6 57.2C13.8 59.6 12.6 56.8 4.2 52C4.2 52 -1.4 42 -15.4 42.4C-15.4 42.4 -58.2 46 -68.6 58C-68.6 58 -55 46.8 -44.6 44C-44.6 44 -22.2 36 -13.8 36.8C-13.8 36.8 11 37.8 18.6 33.8C18.6 33.8 7.4 38.8 10.6 42C13.8 45.2 20.6 52.8 20.6 54C20.6 55.2 44.8 77.3 48.4 81.7L50.6 84z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M189 278C189 278 173.5 241.5 161 232C161 232 187 248 190.5 266C190.5 266 190.5 276 189 278z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M236 285.5C236 285.5 209.5 230.5 191 206.5C191 206.5 234.5 244 239.5 270.5L240 276L237 273.5C237 273.5 236.5 282.5 236 285.5z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M292.5 237C292.5 237 230 177.5 228.5 175C228.5 175 289 241 292 248.5C292 248.5 290 239.5 292.5 237z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M104 280.5C104 280.5 123.5 228.5 142.5 251C142.5 251 157.5 261 157 264C157 264 153 257.5 135 258C135 258 116 255 104 280.5z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M294.5 153C294.5 153 249.5 124.5 242 123C230.193 120.639 291.5 152 296.5 162.5C296.5 162.5 298.5 160 294.5 153z"/>
- </g>
- <g style="fill: #000000">
- <path d="M143.801 259.601C143.801 259.601 164.201 257.601 171.001 250.801L175.401 254.401L193.001 216.001L196.601 221.201C196.601 221.201 211.001 206.401 210.201 198.401C209.401 190.401 223.001 204.401 223.001 204.401C223.001 204.401 222.201 192.801 229.401 199.601C229.401 199.601 227.001 184.001 235.401 192.001C235.401 192.001 224.864 161.844 247.401 187.601C253.001 194.001 248.601 187.201 248.601 187.201C248.601 187.201 222.601 139.201 244.201 153.601C244.201 153.601 246.201 130.801 245.001 126.401C243.801 122.001 241.801 99.6 237.001 94.4C232.201 89.2 237.401 87.6 243.001 92.8C243.001 92.8 231.801 68.8 245.001 80.8C245.001 80.8 241.401 65.6 237.001 62.8C237.001 62.8 231.401 45.6 246.601 56.4C246.601 56.4 242.201 44 239.001 40.8C239.001 40.8 227.401 13.2 234.601 18L239.001 21.6C239.001 21.6 232.201 7.6 238.601 12C245.001 16.4 245.001 16 245.001 16C245.001 16 223.801 -17.2 244.201 0.4C244.201 0.4 236.042 -13.518 232.601 -20.4C232.601 -20.4 213.801 -40.8 228.201 -34.4L233.001 -32.8C233.001 -32.8 224.201 -42.8 216.201 -44.4C208.201 -46 218.601 -52.4 225.001 -50.4C231.401 -48.4 247.001 -40.8 247.001 -40.8C247.001 -40.8 259.801 -22 263.801 -21.6C263.801 -21.6 243.801 -29.2 249.801 -21.2C249.801 -21.2 264.201 -7.2 257.001 -7.6C257.001 -7.6 251.001 -0.4 255.801 8.4C255.801 8.4 237.342 -9.991 252.201 15.6L259.001 32C259.001 32 234.601 7.2 245.801 29.2C245.801 29.2 263.001 52.8 265.001 53.2C267.001 53.6 271.401 62.4 271.401 62.4L267.001 60.4L272.201 69.2C272.201 69.2 261.001 57.2 267.001 70.4L272.601 84.8C272.601 84.8 252.201 62.8 265.801 92.4C265.801 92.4 249.401 87.2 258.201 104.4C258.201 104.4 256.601 120.401 257.001 125.601C257.401 130.801 258.601 159.201 254.201 167.201C249.801 175.201 260.201 194.401 262.201 198.401C264.201 202.401 267.801 213.201 259.001 204.001C250.201 194.801 254.601 200.401 256.601 209.201C258.601 218.001 264.601 233.601 263.801 239.201C263.801 239.201 262.601 240.401 259.401 236.801C259.401 236.801 244.601 214.001 246.201 228.401C246.201 228.401 245.001 236.401 241.801 245.201C241.801 245.201 238.601 256.001 238.601 247.201C238.601 247.201 235.401 230.401 232.601 238.001C229.801 245.601 226.201 251.601 223.401 254.001C220.601 256.401 215.401 233.601 214.201 244.001C214.201 244.001 202.201 231.601 197.401 248.001L185.801 264.401C185.801 264.401 185.401 252.001 184.201 258.001C184.201 258.001 154.201 264.001 143.801 259.601z"/>
- </g>
- <g style="fill: #000000">
- <path d="M109.401 -97.2C109.401 -97.2 97.801 -105.2 93.801 -104.8C89.801 -104.4 121.401 -113.6 162.601 -86C162.601 -86 167.401 -83.2 171.001 -83.6C171.001 -83.6 174.201 -81.2 171.401 -77.6C171.401 -77.6 162.601 -68 173.801 -56.8C173.801 -56.8 192.201 -50 186.601 -58.8C186.601 -58.8 197.401 -54.8 199.801 -50.8C202.201 -46.8 201.001 -50.8 201.001 -50.8C201.001 -50.8 194.601 -58 188.601 -63.2C188.601 -63.2 183.401 -65.2 180.601 -73.6C177.801 -82 175.401 -92 179.801 -95.2C179.801 -95.2 175.801 -90.8 176.601 -94.8C177.401 -98.8 181.001 -102.4 182.601 -102.8C184.201 -103.2 200.601 -119 207.401 -119.4C207.401 -119.4 198.201 -118 195.201 -119C192.201 -120 165.601 -131.4 159.601 -132.6C159.601 -132.6 142.801 -139.2 154.801 -137.2C154.801 -137.2 190.601 -133.4 208.801 -120.2C208.801 -120.2 201.601 -128.6 183.201 -135.6C183.201 -135.6 161.001 -148.2 125.801 -143.2C125.801 -143.2 108.001 -140 100.201 -138.2C100.201 -138.2 97.601 -138.8 97.001 -139.2C96.401 -139.6 84.6 -148.6 57 -141.6C57 -141.6 40 -137 31.4 -132.2C31.4 -132.2 16.2 -131 12.6 -127.8C12.6 -127.8 -6 -113.2 -8 -112.4C-10 -111.6 -21.4 -104 -22.2 -103.6C-22.2 -103.6 2.4 -110.2 4.8 -112.6C7.2 -115 24.6 -117.6 27 -116.2C29.4 -114.8 37.8 -115.4 28.2 -114.8C28.2 -114.8 103.801 -100 104.601 -98C105.401 -96 109.401 -97.2 109.401 -97.2z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M180.801 -106.4C180.801 -106.4 170.601 -113.8 168.601 -113.8C166.601 -113.8 154.201 -124 150.001 -123.6C145.801 -123.2 133.601 -133.2 106.201 -125C106.201 -125 105.601 -127 109.201 -127.8C109.201 -127.8 115.601 -130 116.001 -130.6C116.001 -130.6 136.201 -134.8 143.401 -131.2C143.401 -131.2 152.601 -128.6 158.801 -122.4C158.801 -122.4 170.001 -119.2 173.201 -120.2C173.201 -120.2 182.001 -118 182.401 -116.2C182.401 -116.2 188.201 -113.2 186.401 -110.6C186.401 -110.6 186.801 -109 180.801 -106.4z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M168.33 -108.509C169.137 -107.877 170.156 -107.779 170.761 -106.97C170.995 -106.656 170.706 -106.33 170.391 -106.233C169.348 -105.916 168.292 -106.486 167.15 -105.898C166.748 -105.691 166.106 -105.873 165.553 -106.022C163.921 -106.463 162.092 -106.488 160.401 -105.8C158.416 -106.929 156.056 -106.345 153.975 -107.346C153.917 -107.373 153.695 -107.027 153.621 -107.054C150.575 -108.199 146.832 -107.916 144.401 -110.2C141.973 -110.612 139.616 -111.074 137.188 -111.754C135.37 -112.263 133.961 -113.252 132.341 -114.084C130.964 -114.792 129.507 -115.314 127.973 -115.686C126.11 -116.138 124.279 -116.026 122.386 -116.546C122.293 -116.571 122.101 -116.227 122.019 -116.254C121.695 -116.362 121.405 -116.945 121.234 -116.892C119.553 -116.37 118.065 -117.342 116.401 -117C115.223 -118.224 113.495 -117.979 111.949 -118.421C108.985 -119.269 105.831 -117.999 102.801 -119C106.914 -120.842 111.601 -119.61 115.663 -121.679C117.991 -122.865 120.653 -121.763 123.223 -122.523C123.71 -122.667 124.401 -122.869 124.801 -122.2C124.935 -122.335 125.117 -122.574 125.175 -122.546C127.625 -121.389 129.94 -120.115 132.422 -119.049C132.763 -118.903 133.295 -119.135 133.547 -118.933C135.067 -117.717 137.01 -117.82 138.401 -116.6C140.099 -117.102 141.892 -116.722 143.621 -117.346C143.698 -117.373 143.932 -117.032 143.965 -117.054C145.095 -117.802 146.25 -117.531 147.142 -117.227C147.48 -117.112 148.143 -116.865 148.448 -116.791C149.574 -116.515 150.43 -116.035 151.609 -115.852C151.723 -115.834 151.908 -116.174 151.98 -116.146C153.103 -115.708 154.145 -115.764 154.801 -114.6C154.936 -114.735 155.101 -114.973 155.183 -114.946C156.21 -114.608 156.859 -113.853 157.96 -113.612C158.445 -113.506 159.057 -112.88 159.633 -112.704C162.025 -111.973 163.868 -110.444 166.062 -109.549C166.821 -109.239 167.697 -109.005 168.33 -108.509z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M91.696 -122.739C89.178 -124.464 86.81 -125.57 84.368 -127.356C84.187 -127.489 83.827 -127.319 83.625 -127.441C82.618 -128.05 81.73 -128.631 80.748 -129.327C80.209 -129.709 79.388 -129.698 78.88 -129.956C76.336 -131.248 73.707 -131.806 71.2 -133C71.882 -133.638 73.004 -133.394 73.6 -134.2C73.795 -133.92 74.033 -133.636 74.386 -133.827C76.064 -134.731 77.914 -134.884 79.59 -134.794C81.294 -134.702 83.014 -134.397 84.789 -134.125C85.096 -134.078 85.295 -133.555 85.618 -133.458C87.846 -132.795 90.235 -133.32 92.354 -132.482C93.945 -131.853 95.515 -131.03 96.754 -129.755C97.006 -129.495 96.681 -129.194 96.401 -129C96.789 -129.109 97.062 -128.903 97.173 -128.59C97.257 -128.351 97.257 -128.049 97.173 -127.81C97.061 -127.498 96.782 -127.397 96.408 -127.346C95.001 -127.156 96.773 -128.536 96.073 -128.088C94.8 -127.274 95.546 -125.868 94.801 -124.6C94.521 -124.794 94.291 -125.012 94.401 -125.4C94.635 -124.878 94.033 -124.588 93.865 -124.272C93.48 -123.547 92.581 -122.132 91.696 -122.739z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M59.198 -115.391C56.044 -116.185 52.994 -116.07 49.978 -117.346C49.911 -117.374 49.688 -117.027 49.624 -117.054C48.258 -117.648 47.34 -118.614 46.264 -119.66C45.351 -120.548 43.693 -120.161 42.419 -120.648C42.095 -120.772 41.892 -121.284 41.591 -121.323C40.372 -121.48 39.445 -122.429 38.4 -123C40.736 -123.795 43.147 -123.764 45.609 -124.148C45.722 -124.166 45.867 -123.845 46 -123.845C46.136 -123.845 46.266 -124.066 46.4 -124.2C46.595 -123.92 46.897 -123.594 47.154 -123.848C47.702 -124.388 48.258 -124.198 48.798 -124.158C48.942 -124.148 49.067 -123.845 49.2 -123.845C49.336 -123.845 49.467 -124.156 49.6 -124.156C49.736 -124.155 49.867 -123.845 50 -123.845C50.136 -123.845 50.266 -124.066 50.4 -124.2C51.092 -123.418 51.977 -123.972 52.799 -123.793C53.837 -123.566 54.104 -122.418 55.178 -122.12C59.893 -120.816 64.03 -118.671 68.393 -116.584C68.7 -116.437 68.91 -116.189 68.8 -115.8C69.067 -115.8 69.38 -115.888 69.57 -115.756C70.628 -115.024 71.669 -114.476 72.366 -113.378C72.582 -113.039 72.253 -112.632 72.02 -112.684C67.591 -113.679 63.585 -114.287 59.198 -115.391z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M45.338 -71.179C43.746 -72.398 43.162 -74.429 42.034 -76.221C41.82 -76.561 42.094 -76.875 42.411 -76.964C42.971 -77.123 43.514 -76.645 43.923 -76.443C45.668 -75.581 47.203 -74.339 49.2 -74.2C51.19 -71.966 55.45 -71.581 55.457 -68.2C55.458 -67.341 54.03 -68.259 53.6 -67.4C51.149 -68.403 48.76 -68.3 46.38 -69.767C45.763 -70.148 46.093 -70.601 45.338 -71.179z"/>
- </g>
- <g style="fill: #cc7226">
- <path d="M17.8 -123.756C17.935 -123.755 24.966 -123.522 24.949 -123.408C24.904 -123.099 17.174 -122.05 16.81 -122.22C16.646 -122.296 9.134 -119.866 9 -120C9.268 -120.135 17.534 -123.756 17.8 -123.756z"/>
- </g>
- <g style="fill: #000000">
- <path d="M33.2 -114C33.2 -114 18.4 -112.2 14 -111C9.6 -109.8 -9 -102.2 -12 -100.2C-12 -100.2 -25.4 -94.8 -42.4 -74.8C-42.4 -74.8 -34.8 -78.2 -32.6 -81C-32.6 -81 -19 -93.6 -19.2 -91C-19.2 -91 -7 -99.6 -7.6 -97.4C-7.6 -97.4 16.8 -108.6 14.8 -105.4C14.8 -105.4 36.4 -110 35.4 -108C35.4 -108 54.2 -103.6 51.4 -103.4C51.4 -103.4 45.6 -102.2 52 -98.6C52 -98.6 48.6 -94.2 43.2 -98.2C37.8 -102.2 40.8 -100 35.8 -99C35.8 -99 33.2 -98.2 28.6 -102.2C28.6 -102.2 23 -106.8 14.2 -103.2C14.2 -103.2 -16.4 -90.6 -18.4 -90C-18.4 -90 -22 -87.2 -24.4 -83.6C-24.4 -83.6 -30.2 -79.2 -33.2 -77.8C-33.2 -77.8 -46 -66.2 -47.2 -64.8C-47.2 -64.8 -50.6 -59.6 -51.4 -59.2C-51.4 -59.2 -45 -63 -43 -65C-43 -65 -29 -75 -23.6 -75.8C-23.6 -75.8 -19.2 -78.8 -18.4 -80.2C-18.4 -80.2 -4 -89.4 0.2 -89.4C0.2 -89.4 9.4 -84.2 11.8 -91.2C11.8 -91.2 17.6 -93 23.2 -91.8C23.2 -91.8 26.4 -94.4 25.6 -96.6C25.6 -96.6 27.2 -98.4 28.2 -94.6C28.2 -94.6 31.6 -91 36.4 -93C36.4 -93 40.4 -93.2 38.4 -90.8C38.4 -90.8 34 -87 22.2 -86.8C22.2 -86.8 9.8 -86.2 -6.6 -78.6C-6.6 -78.6 -36.4 -68.2 -45.6 -57.8C-45.6 -57.8 -52 -49 -57.4 -47.8C-57.4 -47.8 -63.2 -47 -69.2 -39.6C-69.2 -39.6 -59.4 -45.4 -50.4 -45.4C-50.4 -45.4 -46.4 -47.8 -50.2 -44.2C-50.2 -44.2 -53.8 -36.6 -52.2 -31.2C-52.2 -31.2 -52.8 -26 -53.6 -24.4C-53.6 -24.4 -61.4 -11.6 -61.4 -9.2C-61.4 -6.8 -60.2 3 -59.8 3.6C-59.4 4.2 -60.8 2 -57 4.4C-53.2 6.8 -50.4 8.4 -49.6 11.2C-48.8 14 -51.6 5.8 -51.8 4C-52 2.2 -56.2 -5 -55.4 -7.4C-55.4 -7.4 -54.4 -6.4 -53.6 -5C-53.6 -5 -54.2 -5.6 -53.6 -9.2C-53.6 -9.2 -52.8 -14.4 -51.4 -17.6C-50 -20.8 -48 -24.6 -47.6 -25.4C-47.2 -26.2 -47.2 -32 -45.8 -29.4L-42.4 -26.8C-42.4 -26.8 -45.2 -29.4 -43 -31.6C-43 -31.6 -44 -37.2 -42.2 -39.8C-42.2 -39.8 -35.2 -48.2 -33.6 -49.2C-32 -50.2 -33.4 -49.8 -33.4 -49.8C-33.4 -49.8 -27.4 -54 -33.2 -52.4C-33.2 -52.4 -37.2 -50.8 -40.2 -50.8C-40.2 -50.8 -47.8 -48.8 -43.8 -53C-39.8 -57.2 -29.8 -62.6 -26 -62.4L-25.2 -60.8L-14 -63.2L-15.2 -62.4C-15.2 -62.4 -15.4 -62.6 -11.2 -63C-7 -63.4 -1.2 -62 0.2 -63.8C1.6 -65.6 5 -66.6 4.6 -65.2C4.2 -63.8 4 -61.8 4 -61.8C4 -61.8 9 -67.6 8.4 -65.4C7.8 -63.2 -0.4 -58 -1.8 -51.8L8.6 -60L12.2 -63C12.2 -63 15.8 -60.8 16 -62.4C16.2 -64 20.8 -69.8 22 -69.6C23.2 -69.4 25.2 -72.2 25 -69.6C24.8 -67 32.4 -61.6 32.4 -61.6C32.4 -61.6 35.6 -63.4 37 -62C38.4 -60.6 42.6 -81.8 42.6 -81.8L67.6 -92.4L111.201 -95.8L94.201 -102.6L33.2 -114z"/>
- </g>
- <g style="stroke:#4c0000; stroke-width:2">
- <path d="M51.4 85C51.4 85 36.4 68.2 28 65.6C28 65.6 14.6 58.8 -10 66.6"/>
- </g>
- <g style="stroke:#4c0000; stroke-width:2">
- <path d="M24.8 64.2C24.8 64.2 -0.4 56.2 -15.8 60.4C-15.8 60.4 -34.2 62.4 -42.6 76.2"/>
- </g>
- <g style="stroke:#4c0000; stroke-width:2">
- <path d="M21.2 63C21.2 63 4.2 55.8 -10.6 53.6C-10.6 53.6 -27.2 51 -43.8 58.2C-43.8 58.2 -56 64.2 -61.4 74.4"/>
- </g>
- <g style="stroke:#4c0000; stroke-width:2">
- <path d="M22.2 63.4C22.2 63.4 6.8 52.4 5.8 51C5.8 51 -1.2 40 -14.2 39.6C-14.2 39.6 -35.6 40.4 -52.8 48.4"/>
- </g>
- <g style="fill: #000000">
- <path d="M20.895 54.407C22.437 55.87 49.4 84.8 49.4 84.8C84.6 121.401 56.6 87.2 56.6 87.2C49 82.4 39.8 63.6 39.8 63.6C38.6 60.8 53.8 70.8 53.8 70.8C57.8 71.6 71.4 90.8 71.4 90.8C64.6 88.4 69.4 95.6 69.4 95.6C72.2 97.6 92.601 113.201 92.601 113.201C96.201 117.201 100.201 118.801 100.201 118.801C114.201 113.601 107.801 126.801 107.801 126.801C110.201 133.601 115.801 122.001 115.801 122.001C127.001 105.2 110.601 107.601 110.601 107.601C80.6 110.401 73.8 94.4 73.8 94.4C71.4 92 80.2 94.4 80.2 94.4C88.601 96.4 73 82 73 82C75.4 82 84.6 88.8 84.6 88.8C95.001 98 97.001 96 97.001 96C115.001 87.2 125.401 94.8 125.401 94.8C127.401 96.4 121.801 103.2 123.401 108.401C125.001 113.601 129.801 126.001 129.801 126.001C127.401 127.601 127.801 138.401 127.801 138.401C144.601 161.601 135.001 159.601 135.001 159.601C119.401 159.201 134.201 166.801 134.201 166.801C137.401 168.801 146.201 176.001 146.201 176.001C143.401 174.801 141.801 180.001 141.801 180.001C146.601 184.001 143.801 188.801 143.801 188.801C137.801 190.001 136.601 194.001 136.601 194.001C143.401 202.001 133.401 202.401 133.401 202.401C137.001 206.801 132.201 218.801 132.201 218.801C127.401 218.801 121.001 224.401 121.001 224.401C123.401 229.201 113.001 234.801 113.001 234.801C104.601 236.401 107.401 243.201 107.401 243.201C99.401 249.201 97.001 265.201 97.001 265.201C96.201 275.601 93.801 278.801 99.001 276.801C104.201 274.801 103.401 262.401 103.401 262.401C98.601 246.801 141.401 230.801 141.401 230.801C145.401 229.201 146.201 224.001 146.201 224.001C148.201 224.401 157.001 232.001 157.001 232.001C164.601 243.201 165.001 234.001 165.001 234.001C166.201 230.401 164.601 224.401 164.601 224.401C170.601 202.801 156.601 196.401 156.601 196.401C146.601 162.801 160.601 171.201 160.601 171.201C163.401 176.801 174.201 182.001 174.201 182.001L177.801 179.601C176.201 174.801 184.601 168.801 184.601 168.801C187.401 175.201 193.401 167.201 193.401 167.201C197.001 142.801 209.401 157.201 209.401 157.201C213.401 158.401 214.601 151.601 214.601 151.601C218.201 141.201 214.601 127.601 214.601 127.601C218.201 127.201 227.801 133.201 227.801 133.201C230.601 129.601 221.401 112.801 225.401 115.201C229.401 117.601 233.801 119.201 233.801 119.201C234.601 117.201 224.601 104.801 224.601 104.801C220.201 102 215.001 81.6 215.001 81.6C222.201 85.2 212.201 70 212.201 70C212.201 66.8 218.201 55.6 218.201 55.6C217.401 48.8 218.201 49.2 218.201 49.2C221.001 50.4 229.001 52 222.201 45.6C215.401 39.2 223.001 34.4 223.001 34.4C227.401 31.6 213.801 32 213.801 32C208.601 27.6 209.001 23.6 209.001 23.6C217.001 25.6 202.601 11.2 200.201 7.6C197.801 4 207.401 -1.2 207.401 -1.2C220.601 -4.8 209.001 -8 209.001 -8C189.401 -7.6 200.201 -18.4 200.201 -18.4C206.201 -18 204.601 -20.4 204.601 -20.4C199.401 -21.6 189.801 -28 189.801 -28C185.801 -31.6 189.401 -30.8 189.401 -30.8C206.201 -29.6 177.401 -40.8 177.401 -40.8C185.401 -40.8 167.401 -51.2 167.401 -51.2C165.401 -52.8 162.201 -60.4 162.201 -60.4C156.201 -65.6 151.401 -72.4 151.401 -72.4C151.001 -76.8 146.201 -81.6 146.201 -81.6C134.601 -95.2 129.001 -94.8 129.001 -94.8C114.201 -98.4 109.001 -97.6 109.001 -97.6L56.2 -93.2C29.8 -80.4 37.6 -59.4 37.6 -59.4C44 -51 53.2 -54.8 53.2 -54.8C57.8 -61 69.4 -58.8 69.4 -58.8C89.801 -55.6 87.201 -59.2 87.201 -59.2C84.801 -63.8 68.6 -70 68.4 -70.6C68.2 -71.2 59.4 -74.6 59.4 -74.6C56.4 -75.8 52 -85 52 -85C48.8 -88.4 64.6 -82.6 64.6 -82.6C63.4 -81.6 70.8 -77.6 70.8 -77.6C88.201 -78.6 98.801 -67.8 98.801 -67.8C109.601 -51.2 109.801 -59.4 109.801 -59.4C112.601 -68.8 100.801 -90 100.801 -90C101.201 -92 109.401 -85.4 109.401 -85.4C110.801 -87.4 111.601 -81.6 111.601 -81.6C111.801 -79.2 115.601 -71.2 115.601 -71.2C118.401 -58.2 122.001 -65.6 122.001 -65.6L126.601 -56.2C128.001 -53.6 122.001 -46 122.001 -46C121.801 -43.2 122.601 -43.4 117.001 -35.8C111.401 -28.2 114.801 -23.8 114.801 -23.8C113.401 -17.2 122.201 -17.6 122.201 -17.6C124.801 -15.4 128.201 -15.4 128.201 -15.4C130.001 -13.4 132.401 -14 132.401 -14C134.001 -17.8 140.201 -15.8 140.201 -15.8C141.601 -18.2 149.801 -18.6 149.801 -18.6C150.801 -21.2 151.201 -22.8 154.601 -23.4C158.001 -24 133.401 -67 133.401 -67C139.801 -67.8 131.601 -80.2 131.601 -80.2C129.401 -86.8 140.801 -72.2 143.001 -70.8C145.201 -69.4 146.201 -67.2 144.601 -67.4C143.001 -67.6 141.201 -65.4 142.601 -65.2C144.001 -65 157.001 -50 160.401 -39.8C163.801 -29.6 169.801 -25.6 176.001 -19.6C182.201 -13.6 181.401 10.6 181.401 10.6C181.001 19.4 187.001 30 187.001 30C189.001 33.8 184.801 52 184.801 52C182.801 54.2 184.201 55 184.201 55C185.201 56.2 192.001 69.4 192.001 69.4C190.201 69.2 193.801 72.8 193.801 72.8C199.001 78.8 192.601 75.8 192.601 75.8C186.601 74.2 193.601 84 193.601 84C194.801 85.8 185.801 81.2 185.801 81.2C176.601 80.6 188.201 87.8 188.201 87.8C196.801 95 185.401 90.6 185.401 90.6C180.801 88.8 184.001 95.6 184.001 95.6C187.201 97.2 204.401 104.2 204.401 104.2C204.801 108.001 201.801 113.001 201.801 113.001C202.201 117.001 200.001 120.401 200.001 120.401C198.801 128.601 198.201 129.401 198.201 129.401C194.001 129.601 186.601 143.401 186.601 143.401C184.801 146.001 174.601 158.001 174.601 158.001C172.601 165.001 154.601 157.801 154.601 157.801C148.001 161.201 150.001 157.801 150.001 157.801C149.601 155.601 154.401 149.601 154.401 149.601C161.401 147.001 158.801 136.201 158.801 136.201C162.801 134.801 151.601 132.001 151.801 130.801C152.001 129.601 157.801 128.201 157.801 128.201C165.801 126.201 161.401 123.801 161.401 123.801C160.801 119.801 163.801 114.201 163.801 114.201C175.401 113.401 163.801 97.2 163.801 97.2C153.001 89.6 152.001 83.8 152.001 83.8C164.601 75.6 156.401 63.2 156.601 59.6C156.801 56 158.001 34.4 158.001 34.4C156.001 28.2 153.001 14.6 153.001 14.6C155.201 9.4 162.601 -3.2 162.601 -3.2C165.401 -7.4 174.201 -12.2 172.001 -15.2C169.801 -18.2 162.001 -16.4 162.001 -16.4C154.201 -17.8 154.801 -12.6 154.801 -12.6C153.201 -11.6 152.401 -6.6 152.401 -6.6C151.68 1.333 142.801 7.6 142.801 7.6C131.601 13.8 140.801 17.8 140.801 17.8C146.801 24.4 137.001 24.6 137.001 24.6C126.001 22.8 134.201 33 134.201 33C145.001 45.8 142.001 48.6 142.001 48.6C131.801 49.6 144.401 58.8 144.401 58.8C144.401 58.8 143.601 56.8 143.801 58.6C144.001 60.4 147.001 64.6 147.801 66.6C148.601 68.6 144.601 68.8 144.601 68.8C145.201 78.4 129.801 74.2 129.801 74.2C129.801 74.2 129.801 74.2 128.201 74.4C126.601 74.6 115.401 73.8 109.601 71.6C103.801 69.4 97.001 69.4 97.001 69.4C97.001 69.4 93.001 71.2 85.4 71C77.8 70.8 69.8 73.6 69.8 73.6C65.4 73.2 74 68.8 74.2 69C74.4 69.2 80 63.6 72 64.2C50.203 65.835 39.4 55.6 39.4 55.6C37.4 54.2 34.8 51.4 34.8 51.4C24.8 49.4 36.2 63.8 36.2 63.8C37.4 65.2 36 66.2 36 66.2C35.2 64.6 27.4 59.2 27.4 59.2C24.589 58.227 23.226 56.893 20.895 54.407z"/>
- </g>
- <g style="fill: #4c0000">
- <path d="M-3 42.8C-3 42.8 8.6 48.4 11.2 51.2C13.8 54 27.8 65.4 27.8 65.4C27.8 65.4 22.4 63.4 19.8 61.6C17.2 59.8 6.4 51.6 6.4 51.6C6.4 51.6 2.6 45.6 -3 42.8z"/>
- </g>
- <g style="fill: #99cc32">
- <path d="M-61.009 11.603C-60.672 11.455 -61.196 8.743 -61.4 8.2C-62.422 5.474 -71.4 4 -71.4 4C-71.627 5.365 -71.682 6.961 -71.576 8.599C-71.576 8.599 -66.708 14.118 -61.009 11.603z"/>
- </g>
- <g style="fill: #659900">
- <path d="M-61.009 11.403C-61.458 11.561 -61.024 8.669 -61.2 8.2C-62.222 5.474 -71.4 3.9 -71.4 3.9C-71.627 5.265 -71.682 6.861 -71.576 8.499C-71.576 8.499 -67.308 13.618 -61.009 11.403z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-65.4 11.546C-66.025 11.546 -66.531 10.406 -66.531 9C-66.531 7.595 -66.025 6.455 -65.4 6.455C-64.775 6.455 -64.268 7.595 -64.268 9C-64.268 10.406 -64.775 11.546 -65.4 11.546z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-65.4 9z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-111 109.601C-111 109.601 -116.6 119.601 -91.8 113.601C-91.8 113.601 -77.8 112.401 -75.4 110.001C-74.2 110.801 -65.834 113.734 -63 114.401C-56.2 116.001 -47.8 106 -47.8 106C-47.8 106 -43.2 95.5 -40.4 95.5C-37.6 95.5 -40.8 97.1 -40.8 97.1C-40.8 97.1 -47.4 107.201 -47 108.801C-47 108.801 -52.2 128.801 -68.2 129.601C-68.2 129.601 -84.35 130.551 -83 136.401C-83 136.401 -74.2 134.001 -71.8 136.401C-71.8 136.401 -61 136.001 -69 142.401L-75.8 154.001C-75.8 154.001 -75.66 157.919 -85.8 154.401C-95.6 151.001 -105.9 138.101 -105.9 138.101C-105.9 138.101 -121.85 123.551 -111 109.601z"/>
- </g>
- <g style="fill: #e59999">
- <path d="M-112.2 113.601C-112.2 113.601 -114.2 123.201 -77.4 112.801C-77.4 112.801 -73 112.801 -70.6 113.601C-68.2 114.401 -56.2 117.201 -54.2 116.001C-54.2 116.001 -61.4 129.601 -73 128.001C-73 128.001 -86.2 129.601 -85.8 134.401C-85.8 134.401 -81.8 141.601 -77 144.001C-77 144.001 -74.2 146.401 -74.6 149.601C-75 152.801 -77.8 154.401 -79.8 155.201C-81.8 156.001 -85 152.801 -86.6 152.801C-88.2 152.801 -96.6 146.401 -101 141.601C-105.4 136.801 -113.8 124.801 -113.4 122.001C-113 119.201 -112.2 113.601 -112.2 113.601z"/>
- </g>
- <g style="fill: #b26565">
- <path d="M-109 131.051C-106.4 135.001 -103.2 139.201 -101 141.601C-96.6 146.401 -88.2 152.801 -86.6 152.801C-85 152.801 -81.8 156.001 -79.8 155.201C-77.8 154.401 -75 152.801 -74.6 149.601C-74.2 146.401 -77 144.001 -77 144.001C-80.066 142.468 -82.806 138.976 -84.385 136.653C-84.385 136.653 -84.2 139.201 -89.4 138.401C-94.6 137.601 -99.8 134.801 -101.4 131.601C-103 128.401 -105.4 126.001 -103.8 129.601C-102.2 133.201 -99.8 136.801 -98.2 137.201C-96.6 137.601 -97 138.801 -99.4 138.401C-101.8 138.001 -104.6 137.601 -109 132.401z"/>
- </g>
- <g style="fill: #992600">
- <path d="M-111.6 110.001C-111.6 110.001 -109.8 96.4 -108.6 92.4C-108.6 92.4 -109.4 85.6 -107 81.4C-104.6 77.2 -102.6 71 -99.6 65.6C-96.6 60.2 -96.4 56.2 -92.4 54.6C-88.4 53 -82.4 44.4 -79.6 43.4C-76.8 42.4 -77 43.2 -77 43.2C-77 43.2 -70.2 28.4 -56.6 32.4C-56.6 32.4 -72.8 29.6 -57 20.2C-57 20.2 -61.8 21.3 -58.5 14.3C-56.299 9.632 -56.8 16.4 -67.8 28.2C-67.8 28.2 -72.8 36.8 -78 39.8C-83.2 42.8 -95.2 49.8 -96.4 53.6C-97.6 57.4 -100.8 63.2 -102.8 64.8C-104.8 66.4 -107.6 70.6 -108 74C-108 74 -109.2 78 -110.6 79.2C-112 80.4 -112.2 83.6 -112.2 85.6C-112.2 87.6 -114.2 90.4 -114 92.8C-114 92.8 -113.2 111.801 -113.6 113.801L-111.6 110.001z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M-120.2 114.601C-120.2 114.601 -122.2 113.201 -126.6 119.201C-126.6 119.201 -119.3 152.201 -119.3 153.601C-119.3 153.601 -118.2 151.501 -119.5 144.301C-120.8 137.101 -121.7 124.401 -121.7 124.401L-120.2 114.601z"/>
- </g>
- <g style="fill: #992600">
- <path d="M-98.6 54C-98.6 54 -116.2 57.2 -115.8 86.4L-116.6 111.201C-116.6 111.201 -117.8 85.6 -119 84C-120.2 82.4 -116.2 71.2 -119.4 77.2C-119.4 77.2 -133.4 91.2 -125.4 112.401C-125.4 112.401 -123.9 115.701 -126.9 111.101C-126.9 111.101 -131.5 98.5 -130.4 92.1C-130.4 92.1 -130.2 89.9 -128.3 87.1C-128.3 87.1 -119.7 75.4 -117 73.1C-117 73.1 -115.2 58.7 -99.8 53.5C-99.8 53.5 -94.1 51.2 -98.6 54z"/>
- </g>
- <g style="fill: #000000">
- <path d="M40.8 -12.2C41.46 -12.554 41.451 -13.524 42.031 -13.697C43.18 -14.041 43.344 -15.108 43.862 -15.892C44.735 -17.211 44.928 -18.744 45.51 -20.235C45.782 -20.935 45.809 -21.89 45.496 -22.55C44.322 -25.031 43.62 -27.48 42.178 -29.906C41.91 -30.356 41.648 -31.15 41.447 -31.748C40.984 -33.132 39.727 -34.123 38.867 -35.443C38.579 -35.884 39.104 -36.809 38.388 -36.893C37.491 -36.998 36.042 -37.578 35.809 -36.552C35.221 -33.965 36.232 -31.442 37.2 -29C36.418 -28.308 36.752 -27.387 36.904 -26.62C37.614 -23.014 36.416 -19.662 35.655 -16.188C35.632 -16.084 35.974 -15.886 35.946 -15.824C34.724 -13.138 33.272 -10.693 31.453 -8.312C30.695 -7.32 29.823 -6.404 29.326 -5.341C28.958 -4.554 28.55 -3.588 28.8 -2.6C25.365 0.18 23.115 4.025 20.504 7.871C20.042 8.551 20.333 9.76 20.884 10.029C21.697 10.427 22.653 9.403 23.123 8.557C23.512 7.859 23.865 7.209 24.356 6.566C24.489 6.391 24.31 5.972 24.445 5.851C27.078 3.504 28.747 0.568 31.2 -1.8C33.15 -2.129 34.687 -3.127 36.435 -4.14C36.743 -4.319 37.267 -4.07 37.557 -4.265C39.31 -5.442 39.308 -7.478 39.414 -9.388C39.464 -10.272 39.66 -11.589 40.8 -12.2z"/>
- </g>
- <g style="fill: #000000">
- <path d="M31.959 -16.666C32.083 -16.743 31.928 -17.166 32.037 -17.382C32.199 -17.706 32.602 -17.894 32.764 -18.218C32.873 -18.434 32.71 -18.814 32.846 -18.956C35.179 -21.403 35.436 -24.427 34.4 -27.4C35.424 -28.02 35.485 -29.282 35.06 -30.129C34.207 -31.829 34.014 -33.755 33.039 -35.298C32.237 -36.567 30.659 -37.811 29.288 -36.508C28.867 -36.108 28.546 -35.321 28.824 -34.609C28.888 -34.446 29.173 -34.3 29.146 -34.218C29.039 -33.894 28.493 -33.67 28.487 -33.398C28.457 -31.902 27.503 -30.391 28.133 -29.062C28.905 -27.433 29.724 -25.576 30.4 -23.8C29.166 -21.684 30.199 -19.235 28.446 -17.358C28.31 -17.212 28.319 -16.826 28.441 -16.624C28.733 -16.138 29.139 -15.732 29.625 -15.44C29.827 -15.319 30.175 -15.317 30.375 -15.441C30.953 -15.803 31.351 -16.29 31.959 -16.666z"/>
- </g>
- <g style="fill: #000000">
- <path d="M94.771 -26.977C96.16 -25.185 96.45 -22.39 94.401 -21C94.951 -17.691 98.302 -19.67 100.401 -20.2C100.292 -20.588 100.519 -20.932 100.802 -20.937C101.859 -20.952 102.539 -21.984 103.601 -21.8C104.035 -23.357 105.673 -24.059 106.317 -25.439C108.043 -29.134 107.452 -33.407 104.868 -36.653C104.666 -36.907 104.883 -37.424 104.759 -37.786C104.003 -39.997 101.935 -40.312 100.001 -41C98.824 -44.875 98.163 -48.906 96.401 -52.6C94.787 -52.85 94.089 -54.589 92.752 -55.309C91.419 -56.028 90.851 -54.449 90.892 -53.403C90.899 -53.198 91.351 -52.974 91.181 -52.609C91.105 -52.445 90.845 -52.334 90.845 -52.2C90.846 -52.065 91.067 -51.934 91.201 -51.8C90.283 -50.98 88.86 -50.503 88.565 -49.358C87.611 -45.648 90.184 -42.523 91.852 -39.322C92.443 -38.187 91.707 -36.916 90.947 -35.708C90.509 -35.013 90.617 -33.886 90.893 -33.03C91.645 -30.699 93.236 -28.96 94.771 -26.977z"/>
- </g>
- <g style="fill: #000000">
- <path d="M57.611 -8.591C56.124 -6.74 52.712 -4.171 55.629 -2.243C55.823 -2.114 56.193 -2.11 56.366 -2.244C58.387 -3.809 60.39 -4.712 62.826 -5.294C62.95 -5.323 63.224 -4.856 63.593 -5.017C65.206 -5.72 67.216 -5.662 68.4 -7C72.167 -6.776 75.732 -7.892 79.123 -9.2C80.284 -9.648 81.554 -10.207 82.755 -10.709C84.131 -11.285 85.335 -12.213 86.447 -13.354C86.58 -13.49 86.934 -13.4 87.201 -13.4C87.161 -14.263 88.123 -14.39 88.37 -15.012C88.462 -15.244 88.312 -15.64 88.445 -15.742C90.583 -17.372 91.503 -19.39 90.334 -21.767C90.049 -22.345 89.8 -22.963 89.234 -23.439C88.149 -24.35 87.047 -23.496 86 -23.8C85.841 -23.172 85.112 -23.344 84.726 -23.146C83.867 -22.707 82.534 -23.292 81.675 -22.854C80.313 -22.159 79.072 -21.99 77.65 -21.613C77.338 -21.531 76.56 -21.627 76.4 -21C76.266 -21.134 76.118 -21.368 76.012 -21.346C74.104 -20.95 72.844 -20.736 71.543 -19.044C71.44 -18.911 70.998 -19.09 70.839 -18.955C69.882 -18.147 69.477 -16.913 68.376 -16.241C68.175 -16.118 67.823 -16.286 67.629 -16.157C66.983 -15.726 66.616 -15.085 65.974 -14.638C65.645 -14.409 65.245 -14.734 65.277 -14.99C65.522 -16.937 66.175 -18.724 65.6 -20.6C67.677 -23.12 70.194 -25.069 72 -27.8C72.015 -29.966 72.707 -32.112 72.594 -34.189C72.584 -34.382 72.296 -35.115 72.17 -35.462C71.858 -36.316 72.764 -37.382 71.92 -38.106C70.516 -39.309 69.224 -38.433 68.4 -37C66.562 -36.61 64.496 -35.917 62.918 -37.151C61.911 -37.938 61.333 -38.844 60.534 -39.9C59.549 -41.202 59.884 -42.638 59.954 -44.202C59.96 -44.33 59.645 -44.466 59.645 -44.6C59.646 -44.735 59.866 -44.866 60 -45C59.294 -45.626 59.019 -46.684 58 -47C58.305 -48.092 57.629 -48.976 56.758 -49.278C54.763 -49.969 53.086 -48.057 51.194 -47.984C50.68 -47.965 50.213 -49.003 49.564 -49.328C49.132 -49.544 48.428 -49.577 48.066 -49.311C47.378 -48.807 46.789 -48.693 46.031 -48.488C44.414 -48.052 43.136 -46.958 41.656 -46.103C40.171 -45.246 39.216 -43.809 38.136 -42.489C37.195 -41.337 37.059 -38.923 38.479 -38.423C40.322 -37.773 41.626 -40.476 43.592 -40.15C43.904 -40.099 44.11 -39.788 44 -39.4C44.389 -39.291 44.607 -39.52 44.8 -39.8C45.658 -38.781 46.822 -38.444 47.76 -37.571C48.73 -36.667 50.476 -37.085 51.491 -36.088C53.02 -34.586 52.461 -31.905 54.4 -30.6C53.814 -29.287 53.207 -28.01 52.872 -26.583C52.59 -25.377 53.584 -24.18 54.795 -24.271C56.053 -24.365 56.315 -25.124 56.8 -26.2C57.067 -25.933 57.536 -25.636 57.495 -25.42C57.038 -23.033 56.011 -21.04 55.553 -18.609C55.494 -18.292 55.189 -18.09 54.8 -18.2C54.332 -14.051 50.28 -11.657 47.735 -8.492C47.332 -7.99 47.328 -6.741 47.737 -6.338C49.14 -4.951 51.1 -6.497 52.8 -7C53.013 -8.206 53.872 -9.148 55.204 -9.092C55.46 -9.082 55.695 -9.624 56.019 -9.754C56.367 -9.892 56.869 -9.668 57.155 -9.866C58.884 -11.061 60.292 -12.167 62.03 -13.356C62.222 -13.487 62.566 -13.328 62.782 -13.436C63.107 -13.598 63.294 -13.985 63.617 -14.17C63.965 -14.37 64.207 -14.08 64.4 -13.8C63.754 -13.451 63.75 -12.494 63.168 -12.292C62.393 -12.024 61.832 -11.511 61.158 -11.064C60.866 -10.871 60.207 -11.119 60.103 -10.94C59.505 -9.912 58.321 -9.474 57.611 -8.591z"/>
- </g>
- <g style="fill: #000000">
- <path d="M2.2 -58C2.2 -58 -7.038 -60.872 -18.2 -35.2C-18.2 -35.2 -20.6 -30 -23 -28C-25.4 -26 -36.6 -22.4 -38.6 -18.4L-49 -2.4C-49 -2.4 -34.2 -18.4 -31 -20.8C-31 -20.8 -23 -29.2 -26.2 -22.4C-26.2 -22.4 -40.2 -11.6 -39 -2.4C-39 -2.4 -44.6 12 -45.4 14C-45.4 14 -29.4 -18 -27 -19.2C-24.6 -20.4 -23.4 -20.4 -24.6 -16.8C-25.8 -13.2 -26.2 3.2 -29 5.2C-29 5.2 -21 -15.2 -21.8 -18.4C-21.8 -18.4 -18.6 -22 -16.2 -16.8L-17.4 -0.8L-13 11.2C-13 11.2 -15.4 0 -13.8 -15.6C-13.8 -15.6 -15.8 -26 -11.8 -20.4C-7.8 -14.8 1.8 -8.8 1.8 -4C1.8 -4 -3.4 -21.6 -12.6 -26.4L-16.6 -20.4L-17.8 -22.4C-17.8 -22.4 -21.4 -23.2 -17 -30C-12.6 -36.8 -13 -37.6 -13 -37.6C-13 -37.6 -6.6 -30.4 -5 -30.4C-5 -30.4 8.2 -38 9.4 -13.6C9.4 -13.6 16.2 -28 7 -34.8C7 -34.8 -7.8 -36.8 -6.6 -42L0.6 -54.4C4.2 -59.6 2.6 -56.8 2.6 -56.8z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-17.8 -41.6C-17.8 -41.6 -30.6 -41.6 -33.8 -36.4L-41 -26.8C-41 -26.8 -23.8 -36.8 -19.8 -38C-15.8 -39.2 -17.8 -41.6 -17.8 -41.6z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-57.8 -35.2C-57.8 -35.2 -59.8 -34 -60.2 -31.2C-60.6 -28.4 -63 -28 -62.2 -25.2C-61.4 -22.4 -59.4 -20 -59.4 -24C-59.4 -28 -57.8 -30 -57 -31.2C-56.2 -32.4 -54.6 -36.8 -57.8 -35.2z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-66.6 26C-66.6 26 -75 22 -78.2 18.4C-81.4 14.8 -80.948 19.966 -85.8 19.6C-91.647 19.159 -90.6 3.2 -90.6 3.2L-94.6 10.8C-94.6 10.8 -95.8 25.2 -87.8 22.8C-83.893 21.628 -82.6 23.2 -84.2 24C-85.8 24.8 -78.6 25.2 -81.4 26.8C-84.2 28.4 -69.8 23.2 -72.2 33.6L-66.6 26z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-79.2 40.4C-79.2 40.4 -94.6 44.8 -98.2 35.2C-98.2 35.2 -103 37.6 -100.8 40.6C-98.6 43.6 -97.4 44 -97.4 44C-97.4 44 -92 45.2 -92.6 46C-93.2 46.8 -95.6 50.2 -95.6 50.2C-95.6 50.2 -85.4 44.2 -79.2 40.4z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M149.201 118.601C148.774 120.735 147.103 121.536 145.201 122.201C143.284 121.243 140.686 118.137 138.801 120.201C138.327 119.721 137.548 119.661 137.204 118.999C136.739 118.101 137.011 117.055 136.669 116.257C136.124 114.985 135.415 113.619 135.601 112.201C137.407 111.489 138.002 109.583 137.528 107.82C137.459 107.563 137.03 107.366 137.23 107.017C137.416 106.694 137.734 106.467 138.001 106.2C137.866 106.335 137.721 106.568 137.61 106.548C137 106.442 137.124 105.805 137.254 105.418C137.839 103.672 139.853 103.408 141.201 104.6C141.457 104.035 141.966 104.229 142.401 104.2C142.351 103.621 142.759 103.094 142.957 102.674C143.475 101.576 145.104 102.682 145.901 102.07C146.977 101.245 148.04 100.546 149.118 101.149C150.927 102.162 152.636 103.374 153.835 105.115C154.41 105.949 154.65 107.23 154.592 108.188C154.554 108.835 153.173 108.483 152.83 109.412C152.185 111.16 154.016 111.679 154.772 113.017C154.97 113.366 154.706 113.67 154.391 113.768C153.98 113.896 153.196 113.707 153.334 114.16C154.306 117.353 151.55 118.031 149.201 118.601z"/>
- </g>
- <g style="fill: #ffffff">
- <path d="M139.6 138.201C139.593 136.463 137.992 134.707 139.201 133.001C139.336 133.135 139.467 133.356 139.601 133.356C139.736 133.356 139.867 133.135 140.001 133.001C141.496 135.217 145.148 136.145 145.006 138.991C144.984 139.438 143.897 140.356 144.801 141.001C142.988 142.349 142.933 144.719 142.001 146.601C140.763 146.315 139.551 145.952 138.401 145.401C138.753 143.915 138.636 142.231 139.456 140.911C139.89 140.213 139.603 139.134 139.6 138.201z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-26.6 129.201C-26.6 129.201 -43.458 139.337 -29.4 124.001C-20.6 114.401 -10.6 108.801 -10.6 108.801C-10.6 108.801 -0.2 104.4 3.4 103.2C7 102 22.2 96.8 25.4 96.4C28.6 96 38.2 92 45 96C51.8 100 59.8 104.4 59.8 104.4C59.8 104.4 43.4 96 39.8 98.4C36.2 100.8 29 100.4 23 103.6C23 103.6 8.2 108.001 5 110.001C1.8 112.001 -8.6 123.601 -10.2 122.801C-11.8 122.001 -9.8 121.601 -8.6 118.801C-7.4 116.001 -9.4 114.401 -17.4 120.801C-25.4 127.201 -26.6 129.201 -26.6 129.201z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-19.195 123.234C-19.195 123.234 -17.785 110.194 -9.307 111.859C-9.307 111.859 -1.081 107.689 1.641 105.721C1.641 105.721 9.78 104.019 11.09 103.402C29.569 94.702 44.288 99.221 44.835 98.101C45.381 96.982 65.006 104.099 68.615 108.185C69.006 108.628 58.384 102.588 48.686 100.697C40.413 99.083 18.811 100.944 7.905 106.48C4.932 107.989 -4.013 113.773 -6.544 113.662C-9.075 113.55 -19.195 123.234 -19.195 123.234z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-23 148.801C-23 148.801 -38.2 146.401 -21.4 144.801C-21.4 144.801 -3.4 142.801 0.6 137.601C0.6 137.601 14.2 128.401 17 128.001C19.8 127.601 49.8 120.401 50.2 118.001C50.6 115.601 56.2 115.601 57.8 116.401C59.4 117.201 58.6 118.401 55.8 119.201C53 120.001 21.8 136.401 15.4 137.601C9 138.801 -2.6 146.401 -7.4 147.601C-12.2 148.801 -23 148.801 -23 148.801z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-3.48 141.403C-3.48 141.403 -12.062 140.574 -3.461 139.755C-3.461 139.755 5.355 136.331 7.403 133.668C7.403 133.668 14.367 128.957 15.8 128.753C17.234 128.548 31.194 124.861 31.399 123.633C31.604 122.404 65.67 109.823 70.09 113.013C73.001 115.114 63.1 113.437 53.466 117.847C52.111 118.467 18.258 133.054 14.981 133.668C11.704 134.283 5.765 138.174 3.307 138.788C0.85 139.403 -3.48 141.403 -3.48 141.403z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-11.4 143.601C-11.4 143.601 -6.2 143.201 -7.4 144.801C-8.6 146.401 -11 145.601 -11 145.601L-11.4 143.601z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-18.6 145.201C-18.6 145.201 -13.4 144.801 -14.6 146.401C-15.8 148.001 -18.2 147.201 -18.2 147.201L-18.6 145.201z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-29 146.801C-29 146.801 -23.8 146.401 -25 148.001C-26.2 149.601 -28.6 148.801 -28.6 148.801L-29 146.801z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-36.6 147.601C-36.6 147.601 -31.4 147.201 -32.6 148.801C-33.8 150.401 -36.2 149.601 -36.2 149.601L-36.6 147.601z"/>
- </g>
- <g style="fill: #000000">
- <path d="M1.8 108.001C1.8 108.001 6.2 108.001 5 109.601C3.8 111.201 0.6 110.801 0.6 110.801L1.8 108.001z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-8.2 113.601C-8.2 113.601 -1.694 111.46 -4.2 114.801C-5.4 116.401 -7.8 115.601 -7.8 115.601L-8.2 113.601z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-19.4 118.401C-19.4 118.401 -14.2 118.001 -15.4 119.601C-16.6 121.201 -19 120.401 -19 120.401L-19.4 118.401z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-27 124.401C-27 124.401 -21.8 124.001 -23 125.601C-24.2 127.201 -26.6 126.401 -26.6 126.401L-27 124.401z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-33.8 129.201C-33.8 129.201 -28.6 128.801 -29.8 130.401C-31 132.001 -33.4 131.201 -33.4 131.201L-33.8 129.201z"/>
- </g>
- <g style="fill: #000000">
- <path d="M5.282 135.598C5.282 135.598 12.203 135.066 10.606 137.195C9.009 139.325 5.814 138.26 5.814 138.26L5.282 135.598z"/>
- </g>
- <g style="fill: #000000">
- <path d="M15.682 130.798C15.682 130.798 22.603 130.266 21.006 132.395C19.409 134.525 16.214 133.46 16.214 133.46L15.682 130.798z"/>
- </g>
- <g style="fill: #000000">
- <path d="M26.482 126.398C26.482 126.398 33.403 125.866 31.806 127.995C30.209 130.125 27.014 129.06 27.014 129.06L26.482 126.398z"/>
- </g>
- <g style="fill: #000000">
- <path d="M36.882 121.598C36.882 121.598 43.803 121.066 42.206 123.195C40.609 125.325 37.414 124.26 37.414 124.26L36.882 121.598z"/>
- </g>
- <g style="fill: #000000">
- <path d="M9.282 103.598C9.282 103.598 16.203 103.066 14.606 105.195C13.009 107.325 9.014 107.06 9.014 107.06L9.282 103.598z"/>
- </g>
- <g style="fill: #000000">
- <path d="M19.282 100.398C19.282 100.398 26.203 99.866 24.606 101.995C23.009 104.125 18.614 103.86 18.614 103.86L19.282 100.398z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-3.4 140.401C-3.4 140.401 1.8 140.001 0.6 141.601C-0.6 143.201 -3 142.401 -3 142.401L-3.4 140.401z"/>
- </g>
- <g style="fill: #992600">
- <path d="M-76.6 41.2C-76.6 41.2 -81 50 -81.4 53.2C-81.4 53.2 -80.6 44.4 -79.4 42.4C-78.2 40.4 -76.6 41.2 -76.6 41.2z"/>
- </g>
- <g style="fill: #992600">
- <path d="M-95 55.2C-95 55.2 -98.2 69.6 -97.8 72.4C-97.8 72.4 -99 60.8 -98.6 59.6C-98.2 58.4 -95 55.2 -95 55.2z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-74.2 -19.4L-74.4 -16.2L-76.6 -16C-76.6 -16 -62.4 -3.4 -61.8 4.2C-61.8 4.2 -61 -4 -74.2 -19.4z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-70.216 -18.135C-70.647 -18.551 -70.428 -19.296 -70.836 -19.556C-71.645 -20.072 -69.538 -20.129 -69.766 -20.845C-70.149 -22.051 -69.962 -22.072 -70.084 -23.348C-70.141 -23.946 -69.553 -25.486 -69.168 -25.926C-67.722 -27.578 -69.046 -30.51 -67.406 -32.061C-67.102 -32.35 -66.726 -32.902 -66.441 -33.32C-65.782 -34.283 -64.598 -34.771 -63.648 -35.599C-63.33 -35.875 -63.531 -36.702 -62.962 -36.61C-62.248 -36.495 -61.007 -36.625 -61.052 -35.784C-61.165 -33.664 -62.494 -31.944 -63.774 -30.276C-63.323 -29.572 -63.781 -28.937 -64.065 -28.38C-65.4 -25.76 -65.211 -22.919 -65.385 -20.079C-65.39 -19.994 -65.697 -19.916 -65.689 -19.863C-65.336 -17.528 -64.752 -15.329 -63.873 -13.1C-63.507 -12.17 -63.036 -11.275 -62.886 -10.348C-62.775 -9.662 -62.672 -8.829 -63.08 -8.124C-61.045 -5.234 -62.354 -2.583 -61.185 0.948C-60.978 1.573 -59.286 3.487 -59.749 3.326C-62.262 2.455 -62.374 2.057 -62.551 1.304C-62.697 0.681 -63.027 -0.696 -63.264 -1.298C-63.328 -1.462 -63.499 -3.346 -63.577 -3.468C-65.09 -5.85 -63.732 -5.674 -65.102 -8.032C-66.53 -8.712 -67.496 -9.816 -68.619 -10.978C-68.817 -11.182 -67.674 -11.906 -67.855 -12.119C-68.947 -13.408 -70.1 -14.175 -69.764 -15.668C-69.609 -16.358 -69.472 -17.415 -70.216 -18.135z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-73.8 -16.4C-73.8 -16.4 -73.4 -9.6 -71 -8C-68.6 -6.4 -69.8 -7.2 -73 -8.4C-76.2 -9.6 -75 -10.4 -75 -10.4C-75 -10.4 -77.8 -10 -75.4 -8C-73 -6 -69.4 -3.6 -71 -3.6C-72.6 -3.6 -80.2 -7.6 -80.2 -10.4C-80.2 -13.2 -81.2 -17.3 -81.2 -17.3C-81.2 -17.3 -80.1 -18.1 -75.3 -18C-75.3 -18 -73.9 -17.3 -73.8 -16.4z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-74.6 2.2C-74.6 2.2 -83.12 -0.591 -101.6 2.8C-101.6 2.8 -92.569 0.722 -73.8 3C-63.5 4.25 -74.6 2.2 -74.6 2.2z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-72.502 2.129C-72.502 2.129 -80.748 -1.389 -99.453 0.392C-99.453 0.392 -90.275 -0.897 -71.774 2.995C-61.62 5.131 -72.502 2.129 -72.502 2.129z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-70.714 2.222C-70.714 2.222 -78.676 -1.899 -97.461 -1.514C-97.461 -1.514 -88.213 -2.118 -70.052 3.14C-60.086 6.025 -70.714 2.222 -70.714 2.222z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-69.444 2.445C-69.444 2.445 -76.268 -1.862 -93.142 -2.96C-93.142 -2.96 -84.803 -2.79 -68.922 3.319C-60.206 6.672 -69.444 2.445 -69.444 2.445z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M45.84 12.961C45.84 12.961 44.91 13.605 45.124 12.424C45.339 11.243 73.547 -1.927 77.161 -1.677C77.161 -1.677 46.913 11.529 45.84 12.961z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M42.446 13.6C42.446 13.6 41.57 14.315 41.691 13.121C41.812 11.927 68.899 -3.418 72.521 -3.452C72.521 -3.452 43.404 12.089 42.446 13.6z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M39.16 14.975C39.16 14.975 38.332 15.747 38.374 14.547C38.416 13.348 58.233 -2.149 68.045 -4.023C68.045 -4.023 50.015 4.104 39.16 14.975z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M36.284 16.838C36.284 16.838 35.539 17.532 35.577 16.453C35.615 15.373 53.449 1.426 62.28 -0.26C62.28 -0.26 46.054 7.054 36.284 16.838z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M4.6 164.801C4.6 164.801 -10.6 162.401 6.2 160.801C6.2 160.801 24.2 158.801 28.2 153.601C28.2 153.601 41.8 144.401 44.6 144.001C47.4 143.601 63.8 140.001 64.2 137.601C64.6 135.201 70.6 132.801 72.2 133.601C73.8 134.401 73.8 143.601 71 144.401C68.2 145.201 49.4 152.401 43 153.601C36.6 154.801 25 162.401 20.2 163.601C15.4 164.801 4.6 164.801 4.6 164.801z"/>
- </g>
- <g style="fill: #000000">
- <path d="M77.6 127.401C77.6 127.401 74.6 129.001 73.4 131.601C73.4 131.601 67 142.201 52.8 145.401C52.8 145.401 29.8 154.401 22 156.401C22 156.401 8.6 161.401 1.2 160.601C1.2 160.601 -5.8 160.801 0.4 162.401C0.4 162.401 20.6 160.401 24 158.601C24 158.601 39.6 153.401 42.6 150.801C45.6 148.201 63.8 143.201 66 141.201C68.2 139.201 78 130.801 77.6 127.401z"/>
- </g>
- <g style="fill: #000000">
- <path d="M18.882 158.911C18.882 158.911 24.111 158.685 22.958 160.234C21.805 161.784 19.357 160.91 19.357 160.91L18.882 158.911z"/>
- </g>
- <g style="fill: #000000">
- <path d="M11.68 160.263C11.68 160.263 16.908 160.037 15.756 161.586C14.603 163.136 12.155 162.263 12.155 162.263L11.68 160.263z"/>
- </g>
- <g style="fill: #000000">
- <path d="M1.251 161.511C1.251 161.511 6.48 161.284 5.327 162.834C4.174 164.383 1.726 163.51 1.726 163.51L1.251 161.511z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-6.383 162.055C-6.383 162.055 -1.154 161.829 -2.307 163.378C-3.46 164.928 -5.908 164.054 -5.908 164.054L-6.383 162.055z"/>
- </g>
- <g style="fill: #000000">
- <path d="M35.415 151.513C35.415 151.513 42.375 151.212 40.84 153.274C39.306 155.336 36.047 154.174 36.047 154.174L35.415 151.513z"/>
- </g>
- <g style="fill: #000000">
- <path d="M45.73 147.088C45.73 147.088 51.689 143.787 51.155 148.849C50.885 151.405 46.362 149.749 46.362 149.749L45.73 147.088z"/>
- </g>
- <g style="fill: #000000">
- <path d="M54.862 144.274C54.862 144.274 62.021 140.573 60.287 146.035C59.509 148.485 55.493 146.935 55.493 146.935L54.862 144.274z"/>
- </g>
- <g style="fill: #000000">
- <path d="M64.376 139.449C64.376 139.449 68.735 134.548 69.801 141.21C70.207 143.748 65.008 142.11 65.008 142.11L64.376 139.449z"/>
- </g>
- <g style="fill: #000000">
- <path d="M26.834 155.997C26.834 155.997 32.062 155.77 30.91 157.32C29.757 158.869 27.308 157.996 27.308 157.996L26.834 155.997z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M62.434 34.603C62.434 34.603 61.708 35.268 61.707 34.197C61.707 33.127 79.191 19.863 88.034 18.479C88.034 18.479 71.935 25.208 62.434 34.603z"/>
- </g>
- <g style="fill: #000000">
- <path d="M65.4 98.4C65.4 98.4 87.401 120.801 96.601 124.401C96.601 124.401 105.801 135.601 101.801 161.601C101.801 161.601 98.601 169.201 95.401 148.401C95.401 148.401 98.601 123.201 87.401 139.201C87.401 139.201 79 129.301 85.4 129.601C85.4 129.601 88.601 131.601 89.001 130.001C89.401 128.401 81.4 114.801 64.2 100.4C47 86 65.4 98.4 65.4 98.4z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M7 137.201C7 137.201 6.8 135.401 8.6 136.201C10.4 137.001 104.601 143.201 136.201 167.201C136.201 167.201 91.001 144.001 7 137.201z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M17.4 132.801C17.4 132.801 17.2 131.001 19 131.801C20.8 132.601 157.401 131.601 181.001 164.001C181.001 164.001 159.001 138.801 17.4 132.801z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M29 128.801C29 128.801 28.8 127.001 30.6 127.801C32.4 128.601 205.801 115.601 229.401 148.001C229.401 148.001 219.801 122.401 29 128.801z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M39 124.001C39 124.001 38.8 122.201 40.6 123.001C42.4 123.801 164.601 85.2 188.201 117.601C188.201 117.601 174.801 93 39 124.001z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-19 146.801C-19 146.801 -19.2 145.001 -17.4 145.801C-15.6 146.601 2.2 148.801 4.2 187.601C4.2 187.601 -3 145.601 -19 146.801z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-27.8 148.401C-27.8 148.401 -28 146.601 -26.2 147.401C-24.4 148.201 -10.2 143.601 -13 182.401C-13 182.401 -11.8 147.201 -27.8 148.401z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-35.8 148.801C-35.8 148.801 -36 147.001 -34.2 147.801C-32.4 148.601 -17 149.201 -29.4 171.601C-29.4 171.601 -19.8 147.601 -35.8 148.801z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M11.526 104.465C11.526 104.465 11.082 106.464 12.631 105.247C28.699 92.622 61.141 33.72 116.826 28.086C116.826 28.086 78.518 15.976 11.526 104.465z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M22.726 102.665C22.726 102.665 21.363 101.472 23.231 100.847C25.099 100.222 137.541 27.72 176.826 35.686C176.826 35.686 149.719 28.176 22.726 102.665z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M1.885 108.767C1.885 108.767 1.376 110.366 3.087 109.39C12.062 104.27 15.677 47.059 59.254 45.804C59.254 45.804 26.843 31.09 1.885 108.767z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-18.038 119.793C-18.038 119.793 -19.115 121.079 -17.162 120.825C-6.916 119.493 14.489 78.222 58.928 83.301C58.928 83.301 26.962 68.955 -18.038 119.793z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-6.8 113.667C-6.8 113.667 -7.611 115.136 -5.742 114.511C4.057 111.237 17.141 66.625 61.729 63.078C61.729 63.078 27.603 55.135 -6.8 113.667z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-25.078 124.912C-25.078 124.912 -25.951 125.954 -24.369 125.748C-16.07 124.669 1.268 91.24 37.264 95.354C37.264 95.354 11.371 83.734 -25.078 124.912z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-32.677 130.821C-32.677 130.821 -33.682 131.866 -32.091 131.748C-27.923 131.439 2.715 98.36 21.183 113.862C21.183 113.862 9.168 95.139 -32.677 130.821z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M36.855 98.898C36.855 98.898 35.654 97.543 37.586 97.158C39.518 96.774 160.221 39.061 198.184 51.927C198.184 51.927 172.243 41.053 36.855 98.898z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M3.4 163.201C3.4 163.201 3.2 161.401 5 162.201C6.8 163.001 22.2 163.601 9.8 186.001C9.8 186.001 19.4 162.001 3.4 163.201z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M13.8 161.601C13.8 161.601 13.6 159.801 15.4 160.601C17.2 161.401 35 163.601 37 202.401C37 202.401 29.8 160.401 13.8 161.601z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M20.6 160.001C20.6 160.001 20.4 158.201 22.2 159.001C24 159.801 48.6 163.201 72.2 195.601C72.2 195.601 36.6 158.801 20.6 160.001z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M28.225 157.972C28.225 157.972 27.788 156.214 29.678 156.768C31.568 157.322 52.002 155.423 90.099 189.599C90.099 189.599 43.924 154.656 28.225 157.972z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M38.625 153.572C38.625 153.572 38.188 151.814 40.078 152.368C41.968 152.922 76.802 157.423 128.499 192.399C128.499 192.399 54.324 150.256 38.625 153.572z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-1.8 142.001C-1.8 142.001 -2 140.201 -0.2 141.001C1.6 141.801 55 144.401 85.4 171.201C85.4 171.201 50.499 146.426 -1.8 142.001z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M-11.8 146.001C-11.8 146.001 -12 144.201 -10.2 145.001C-8.4 145.801 16.2 149.201 39.8 181.601C39.8 181.601 4.2 144.801 -11.8 146.001z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M49.503 148.962C49.503 148.962 48.938 147.241 50.864 147.655C52.79 148.068 87.86 150.004 141.981 181.098C141.981 181.098 64.317 146.704 49.503 148.962z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M57.903 146.562C57.903 146.562 57.338 144.841 59.264 145.255C61.19 145.668 96.26 147.604 150.381 178.698C150.381 178.698 73.317 143.904 57.903 146.562z"/>
- </g>
- <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
- <path d="M67.503 141.562C67.503 141.562 66.938 139.841 68.864 140.255C70.79 140.668 113.86 145.004 203.582 179.298C203.582 179.298 82.917 138.904 67.503 141.562z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-43.8 148.401C-43.8 148.401 -38.6 148.001 -39.8 149.601C-41 151.201 -43.4 150.401 -43.4 150.401L-43.8 148.401z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-13 162.401C-13 162.401 -7.8 162.001 -9 163.601C-10.2 165.201 -12.6 164.401 -12.6 164.401L-13 162.401z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-21.8 162.001C-21.8 162.001 -16.6 161.601 -17.8 163.201C-19 164.801 -21.4 164.001 -21.4 164.001L-21.8 162.001z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-117.169 150.182C-117.169 150.182 -112.124 151.505 -113.782 152.624C-115.439 153.744 -117.446 152.202 -117.446 152.202L-117.169 150.182z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-115.169 140.582C-115.169 140.582 -110.124 141.905 -111.782 143.024C-113.439 144.144 -115.446 142.602 -115.446 142.602L-115.169 140.582z"/>
- </g>
- <g style="fill: #000000">
- <path d="M-122.369 136.182C-122.369 136.182 -117.324 137.505 -118.982 138.624C-120.639 139.744 -122.646 138.202 -122.646 138.202L-122.369 136.182z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-42.6 211.201C-42.6 211.201 -44.2 211.201 -48.2 213.201C-50.2 213.201 -61.4 216.801 -67 226.801C-67 226.801 -54.6 217.201 -42.6 211.201z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M45.116 303.847C45.257 304.105 45.312 304.525 45.604 304.542C46.262 304.582 47.495 304.883 47.37 304.247C46.522 299.941 45.648 295.004 41.515 293.197C40.876 292.918 39.434 293.331 39.36 294.215C39.233 295.739 39.116 297.088 39.425 298.554C39.725 299.975 41.883 299.985 42.8 298.601C43.736 300.273 44.168 302.116 45.116 303.847z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M34.038 308.581C34.786 309.994 34.659 311.853 36.074 312.416C36.814 312.71 38.664 311.735 38.246 310.661C37.444 308.6 37.056 306.361 35.667 304.55C35.467 304.288 35.707 303.755 35.547 303.427C34.953 302.207 33.808 301.472 32.4 301.801C31.285 304.004 32.433 306.133 33.955 307.842C34.091 307.994 33.925 308.37 34.038 308.581z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-5.564 303.391C-5.672 303.014 -5.71 302.551 -5.545 302.23C-5.014 301.197 -4.221 300.075 -4.558 299.053C-4.906 297.997 -6.022 298.179 -6.672 298.748C-7.807 299.742 -7.856 301.568 -8.547 302.927C-8.743 303.313 -8.692 303.886 -9.133 304.277C-9.607 304.698 -10.047 306.222 -9.951 306.793C-9.898 307.106 -10.081 317.014 -9.859 316.751C-9.24 316.018 -6.19 306.284 -6.121 305.392C-6.064 304.661 -5.332 304.196 -5.564 303.391z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-31.202 296.599C-28.568 294.1 -25.778 291.139 -26.22 287.427C-26.336 286.451 -28.111 286.978 -28.298 287.824C-29.1 291.449 -31.139 294.11 -33.707 296.502C-35.903 298.549 -37.765 304.893 -38 305.401C-34.303 300.145 -32.046 297.399 -31.202 296.599z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-44.776 290.635C-44.253 290.265 -44.555 289.774 -44.338 289.442C-43.385 287.984 -42.084 286.738 -42.066 285C-42.063 284.723 -42.441 284.414 -42.776 284.638C-43.053 284.822 -43.395 284.952 -43.503 285.082C-45.533 287.531 -46.933 290.202 -48.376 293.014C-48.559 293.371 -49.703 297.862 -49.39 297.973C-49.151 298.058 -47.431 293.877 -47.221 293.763C-45.958 293.077 -45.946 291.462 -44.776 290.635z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-28.043 310.179C-27.599 309.31 -26.023 308.108 -26.136 307.219C-26.254 306.291 -25.786 304.848 -26.698 305.536C-27.955 306.484 -31.404 307.833 -31.674 313.641C-31.7 314.212 -28.726 311.519 -28.043 310.179z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-13.6 293.001C-13.2 292.333 -12.492 292.806 -12.033 292.543C-11.385 292.171 -10.774 291.613 -10.482 290.964C-9.512 288.815 -7.743 286.995 -7.6 284.601C-9.091 283.196 -9.77 285.236 -10.4 286.201C-11.723 284.554 -12.722 286.428 -14.022 286.947C-14.092 286.975 -14.305 286.628 -14.38 286.655C-15.557 287.095 -16.237 288.176 -17.235 288.957C-17.406 289.091 -17.811 288.911 -17.958 289.047C-18.61 289.65 -19.583 289.975 -19.863 290.657C-20.973 293.364 -24.113 295.459 -26 303.001C-25.619 303.91 -21.488 296.359 -21.001 295.661C-20.165 294.465 -20.047 297.322 -18.771 296.656C-18.72 296.629 -18.534 296.867 -18.4 297.001C-18.206 296.721 -17.988 296.492 -17.6 296.601C-17.6 296.201 -17.734 295.645 -17.533 295.486C-16.296 294.509 -16.38 293.441 -15.6 292.201C-15.142 292.99 -14.081 292.271 -13.6 293.001z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M46.2 347.401C46.2 347.401 53.6 327.001 49.2 315.801C49.2 315.801 60.6 337.401 56 348.601C56 348.601 55.6 338.201 51.6 333.201C51.6 333.201 47.6 346.001 46.2 347.401z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M31.4 344.801C31.4 344.801 36.8 336.001 28.8 317.601C28.8 317.601 28 338.001 21.2 349.001C21.2 349.001 35.4 328.801 31.4 344.801z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M21.4 342.801C21.4 342.801 21.2 322.801 21.6 319.801C21.6 319.801 17.8 336.401 7.6 346.001C7.6 346.001 22 334.001 21.4 342.801z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M11.8 310.801C11.8 310.801 17.8 324.401 7.8 342.801C7.8 342.801 14.2 330.601 9.4 323.601C9.4 323.601 12 320.201 11.8 310.801z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-7.4 342.401C-7.4 342.401 -8.4 326.801 -6.6 324.601C-6.6 324.601 -6.4 318.201 -6.8 317.201C-6.8 317.201 -2.8 311.001 -2.6 318.401C-2.6 318.401 -1.2 326.201 1.6 330.801C1.6 330.801 5.2 336.201 5 342.601C5 342.601 -5 312.401 -7.4 342.401z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-11 314.801C-11 314.801 -17.6 325.601 -19.4 344.601C-19.4 344.601 -20.8 338.401 -17 324.001C-17 324.001 -12.8 308.601 -11 314.801z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-32.8 334.601C-32.8 334.601 -27.8 329.201 -26.4 324.201C-26.4 324.201 -22.8 308.401 -29.2 317.001C-29.2 317.001 -29 325.001 -37.2 332.401C-37.2 332.401 -32.4 330.001 -32.8 334.601z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-38.6 329.601C-38.6 329.601 -35.2 312.201 -34.4 311.401C-34.4 311.401 -32.6 308.001 -35.4 311.201C-35.4 311.201 -44.2 330.401 -48.2 337.001C-48.2 337.001 -40.2 327.801 -38.6 329.601z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-44.4 313.001C-44.4 313.001 -32.8 290.601 -54.6 316.401C-54.6 316.401 -43.6 306.601 -44.4 313.001z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M-59.8 298.401C-59.8 298.401 -55 279.601 -52.4 279.801C-52.4 279.801 -44.2 270.801 -50.8 281.401C-50.8 281.401 -56.8 291.001 -56.2 300.801C-56.2 300.801 -56.8 291.201 -59.8 298.401z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M270.5 287C270.5 287 258.5 277 256 273.5C256 273.5 269.5 292 269.5 299C269.5 299 272 291.5 270.5 287z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M276 265C276 265 255 250 251.5 242.5C251.5 242.5 278 272 278 276.5C278 276.5 278.5 267.5 276 265z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M293 111C293 111 281 103 279.5 105C279.5 105 290 111.5 292.5 120C292.5 120 291 111 293 111z"/>
- </g>
- <g style="fill: #cccccc">
- <path d="M301.5 191.5L284 179.5C284 179.5 303 196.5 303.5 200.5L301.5 191.5z"/>
- </g>
- <g style="stroke:#000000">
- <path d="M-89.25 169L-67.25 173.75"/>
- </g>
- <g style="stroke:#000000">
- <path d="M-39 331C-39 331 -39.5 327.5 -48.5 338"/>
- </g>
- <g style="stroke:#000000">
- <path d="M-33.5 336C-33.5 336 -31.5 329.5 -38 334"/>
- </g>
- <g style="stroke:#000000">
- <path d="M20.5 344.5C20.5 344.5 22 333.5 10.5 346.5"/>
- </g>
-</g>
-</svg>
+<?xml version = "1.0" standalone = "no"?> +<!DOCTYPE svg SYSTEM "svg-19990812.dtd"> +<svg width = "600px" height="600px"> +<title>A less cute tiger +</title> +<g transform="translate(190,150)"> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-122.304 84.285C-122.304 84.285 -122.203 86.179 -123.027 86.16C-123.851 86.141 -140.305 38.066 -160.833 40.309C-160.833 40.309 -143.05 32.956 -122.304 84.285z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-118.774 81.262C-118.774 81.262 -119.323 83.078 -120.092 82.779C-120.86 82.481 -119.977 31.675 -140.043 26.801C-140.043 26.801 -120.82 25.937 -118.774 81.262z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-91.284 123.59C-91.284 123.59 -89.648 124.55 -90.118 125.227C-90.589 125.904 -139.763 113.102 -149.218 131.459C-149.218 131.459 -145.539 112.572 -91.284 123.59z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-94.093 133.801C-94.093 133.801 -92.237 134.197 -92.471 134.988C-92.704 135.779 -143.407 139.121 -146.597 159.522C-146.597 159.522 -149.055 140.437 -94.093 133.801z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-98.304 128.276C-98.304 128.276 -96.526 128.939 -96.872 129.687C-97.218 130.435 -147.866 126.346 -153.998 146.064C-153.998 146.064 -153.646 126.825 -98.304 128.276z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-109.009 110.072C-109.009 110.072 -107.701 111.446 -108.34 111.967C-108.979 112.488 -152.722 86.634 -166.869 101.676C-166.869 101.676 -158.128 84.533 -109.009 110.072z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-116.554 114.263C-116.554 114.263 -115.098 115.48 -115.674 116.071C-116.25 116.661 -162.638 95.922 -174.992 112.469C-174.992 112.469 -168.247 94.447 -116.554 114.263z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-119.154 118.335C-119.154 118.335 -117.546 119.343 -118.036 120.006C-118.526 120.669 -167.308 106.446 -177.291 124.522C-177.291 124.522 -173.066 105.749 -119.154 118.335z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-108.42 118.949C-108.42 118.949 -107.298 120.48 -107.999 120.915C-108.7 121.35 -148.769 90.102 -164.727 103.207C-164.727 103.207 -153.862 87.326 -108.42 118.949z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-128.2 90C-128.2 90 -127.6 91.8 -128.4 92C-129.2 92.2 -157.8 50.2 -177.001 57.8C-177.001 57.8 -161.8 46 -128.2 90z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-127.505 96.979C-127.505 96.979 -126.53 98.608 -127.269 98.975C-128.007 99.343 -164.992 64.499 -182.101 76.061C-182.101 76.061 -169.804 61.261 -127.505 96.979z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172"> + <path d="M-127.62 101.349C-127.62 101.349 -126.498 102.88 -127.199 103.315C-127.9 103.749 -167.969 72.502 -183.927 85.607C-183.927 85.607 -173.062 69.726 -127.62 101.349z"/> + </g> + <g style="fill: #ffffff; stroke:#000000"> + <path d="M-129.83 103.065C-129.327 109.113 -128.339 115.682 -126.6 118.801C-126.6 118.801 -130.2 131.201 -121.4 144.401C-121.4 144.401 -121.8 151.601 -120.2 154.801C-120.2 154.801 -116.2 163.201 -111.4 164.001C-107.516 164.648 -98.793 167.717 -88.932 169.121C-88.932 169.121 -71.8 183.201 -75 196.001C-75 196.001 -75.4 212.401 -79 214.001C-79 214.001 -67.4 202.801 -77 219.601L-81.4 238.401C-81.4 238.401 -55.8 216.801 -71.4 235.201L-81.4 261.201C-81.4 261.201 -61.8 242.801 -69 251.201L-72.2 260.001C-72.2 260.001 -29 232.801 -59.8 262.401C-59.8 262.401 -51.8 258.801 -47.4 261.601C-47.4 261.601 -40.6 260.401 -41.4 262.001C-41.4 262.001 -62.2 272.401 -65.8 290.801C-65.8 290.801 -57.4 280.801 -60.6 291.601L-60.2 303.201C-60.2 303.201 -56.2 281.601 -56.6 319.201C-56.6 319.201 -37.4 301.201 -49 322.001L-49 338.801C-49 338.801 -33.8 322.401 -40.2 335.201C-40.2 335.201 -30.2 326.401 -34.2 341.601C-34.2 341.601 -35 352.001 -30.6 340.801C-30.6 340.801 -14.6 310.201 -20.6 336.401C-20.6 336.401 -21.4 355.601 -16.6 340.801C-16.6 340.801 -16.2 351.201 -7 358.401C-7 358.401 -8.2 307.601 4.6 343.601L8.6 360.001C8.6 360.001 11.4 350.801 11 345.601C11 345.601 25.8 329.201 19 353.601C19 353.601 34.2 330.801 31 344.001C31 344.001 23.4 360.001 25 364.801C25 364.801 41.8 330.001 43 328.401C43 328.401 41 370.802 51.8 334.801C51.8 334.801 57.4 346.801 54.6 351.201C54.6 351.201 62.6 343.201 61.8 340.001C61.8 340.001 66.4 331.801 69.2 345.401C69.2 345.401 71 354.801 72.6 351.601C72.6 351.601 76.6 375.602 77.8 352.801C77.8 352.801 79.4 339.201 72.2 327.601C72.2 327.601 73 324.401 70.2 320.401C70.2 320.401 83.8 342.001 76.6 313.201C76.6 313.201 87.801 321.201 89.001 321.201C89.001 321.201 75.4 298.001 84.2 302.801C84.2 302.801 79 292.401 97.001 304.401C97.001 304.401 81 288.401 98.601 298.001C98.601 298.001 106.601 304.401 99.001 294.401C99.001 294.401 84.6 278.401 106.601 296.401C106.601 296.401 118.201 312.801 119.001 315.601C119.001 315.601 109.001 286.401 104.601 283.601C104.601 283.601 113.001 247.201 154.201 262.801C154.201 262.801 161.001 280.001 165.401 261.601C165.401 261.601 178.201 255.201 189.401 282.801C189.401 282.801 193.401 269.201 192.601 266.401C192.601 266.401 199.401 267.601 198.601 266.401C198.601 266.401 211.801 270.801 213.001 270.001C213.001 270.001 219.801 276.801 220.201 273.201C220.201 273.201 229.401 276.001 227.401 272.401C227.401 272.401 236.201 288.001 236.601 291.601L239.001 277.601L241.001 280.401C241.001 280.401 242.601 272.801 241.801 271.601C241.001 270.401 261.801 278.401 266.601 299.201L268.601 307.601C268.601 307.601 274.601 292.801 273.001 288.801C273.001 288.801 278.201 289.601 278.601 294.001C278.601 294.001 282.601 270.801 277.801 264.801C277.801 264.801 282.201 264.001 283.401 267.601L283.401 260.401C283.401 260.401 290.601 261.201 290.601 258.801C290.601 258.801 295.001 254.801 297.001 259.601C297.001 259.601 284.601 224.401 303.001 243.601C303.001 243.601 310.201 254.401 306.601 235.601C303.001 216.801 299.001 215.201 303.801 214.801C303.801 214.801 304.601 211.201 302.601 209.601C300.601 208.001 303.801 209.601 303.801 209.601C303.801 209.601 308.601 213.601 303.401 191.601C303.401 191.601 309.801 193.201 297.801 164.001C297.801 164.001 300.601 161.601 296.601 153.201C296.601 153.201 304.601 157.601 307.401 156.001C307.401 156.001 307.001 154.401 303.801 150.401C303.801 150.401 282.201 95.6 302.601 117.601C302.601 117.601 314.451 131.151 308.051 108.351C308.051 108.351 298.94 84.341 299.717 80.045L-129.83 103.065z"/> + </g> + <g style="fill: #cc7226; stroke:#000000"> + <path d="M299.717 80.245C300.345 80.426 302.551 81.55 303.801 83.2C303.801 83.2 310.601 94 305.401 75.6C305.401 75.6 296.201 46.8 305.001 58C305.001 58 311.001 65.2 307.801 51.6C303.936 35.173 301.401 28.8 301.401 28.8C301.401 28.8 313.001 33.6 286.201 -6L295.001 -2.4C295.001 -2.4 275.401 -42 253.801 -47.2L245.801 -53.2C245.801 -53.2 284.201 -91.2 271.401 -128C271.401 -128 264.601 -133.2 255.001 -124C255.001 -124 248.601 -119.2 242.601 -120.8C242.601 -120.8 211.801 -119.6 209.801 -119.6C207.801 -119.6 173.001 -156.8 107.401 -139.2C107.401 -139.2 102.201 -137.2 97.801 -138.4C97.801 -138.4 79.4 -154.4 30.6 -131.6C30.6 -131.6 20.6 -129.6 19 -129.6C17.4 -129.6 14.6 -129.6 6.6 -123.2C-1.4 -116.8 -1.8 -116 -3.8 -114.4C-3.8 -114.4 -20.2 -103.2 -25 -102.4C-25 -102.4 -36.6 -96 -41 -86L-44.6 -84.8C-44.6 -84.8 -46.2 -77.6 -46.6 -76.4C-46.6 -76.4 -51.4 -72.8 -52.2 -67.2C-52.2 -67.2 -61 -61.2 -60.6 -56.8C-60.6 -56.8 -62.2 -51.6 -63 -46.8C-63 -46.8 -70.2 -42 -69.4 -39.2C-69.4 -39.2 -77 -25.2 -75.8 -18.4C-75.8 -18.4 -82.2 -18.8 -85 -16.4C-85 -16.4 -85.8 -11.6 -87.4 -11.2C-87.4 -11.2 -90.2 -10 -87.8 -6C-87.8 -6 -89.4 -3.2 -89.8 -1.6C-89.8 -1.6 -89 1.2 -93.4 6.8C-93.4 6.8 -99.8 25.6 -97.8 30.8C-97.8 30.8 -97.4 35.6 -100.2 37.2C-100.2 37.2 -103.8 36.8 -95.4 48.8C-95.4 48.8 -94.6 50 -97.8 52.4C-97.8 52.4 -115 56 -117.4 72.4C-117.4 72.4 -131 87.2 -131 92.4C-131 94.705 -130.729 97.852 -130.03 102.465C-130.03 102.465 -130.6 110.801 -103 111.601C-75.4 112.401 299.717 80.245 299.717 80.245z"/> + </g> + <g style="fill: #cc7226"> + <path d="M-115.6 102.6C-140.6 63.2 -126.2 119.601 -126.2 119.601C-117.4 154.001 12.2 116.401 12.2 116.401C12.2 116.401 181.001 86 192.201 82C203.401 78 298.601 84.4 298.601 84.4L293.001 67.6C228.201 21.2 209.001 44.4 195.401 40.4C181.801 36.4 184.201 46 181.001 46.8C177.801 47.6 138.601 22.8 132.201 23.6C125.801 24.4 100.459 0.649 115.401 32.4C131.401 66.4 57 71.6 40.2 60.4C23.4 49.2 47.4 78.8 47.4 78.8C65.8 98.8 31.4 82 31.4 82C-3 69.2 -27 94.8 -30.2 95.6C-33.4 96.4 -38.2 99.6 -39 93.2C-39.8 86.8 -47.31 70.099 -79 96.4C-99 113.001 -112.8 91 -112.8 91L-115.6 102.6z"/> + </g> + <g style="fill: #e87f3a"> + <path d="M133.51 25.346C127.11 26.146 101.743 2.407 116.71 34.146C133.31 69.346 58.31 73.346 41.51 62.146C24.709 50.946 48.71 80.546 48.71 80.546C67.11 100.546 32.709 83.746 32.709 83.746C-1.691 70.946 -25.691 96.546 -28.891 97.346C-32.091 98.146 -36.891 101.346 -37.691 94.946C-38.491 88.546 -45.87 72.012 -77.691 98.146C-98.927 115.492 -112.418 94.037 -112.418 94.037L-115.618 104.146C-140.618 64.346 -125.546 122.655 -125.546 122.655C-116.745 157.056 13.509 118.146 13.509 118.146C13.509 118.146 182.31 87.746 193.51 83.746C204.71 79.746 299.038 86.073 299.038 86.073L293.51 68.764C228.71 22.364 210.31 46.146 196.71 42.146C183.11 38.146 185.51 47.746 182.31 48.546C179.11 49.346 139.91 24.546 133.51 25.346z"/> + </g> + <g style="fill: #ea8c4d"> + <path d="M134.819 27.091C128.419 27.891 103.685 3.862 118.019 35.891C134.219 72.092 59.619 75.092 42.819 63.892C26.019 52.692 50.019 82.292 50.019 82.292C68.419 102.292 34.019 85.492 34.019 85.492C-0.381 72.692 -24.382 98.292 -27.582 99.092C-30.782 99.892 -35.582 103.092 -36.382 96.692C-37.182 90.292 -44.43 73.925 -76.382 99.892C-98.855 117.983 -112.036 97.074 -112.036 97.074L-115.636 105.692C-139.436 66.692 -124.891 125.71 -124.891 125.71C-116.091 160.11 14.819 119.892 14.819 119.892C14.819 119.892 183.619 89.492 194.819 85.492C206.019 81.492 299.474 87.746 299.474 87.746L294.02 69.928C229.219 23.528 211.619 47.891 198.019 43.891C184.419 39.891 186.819 49.491 183.619 50.292C180.419 51.092 141.219 26.291 134.819 27.091z"/> + </g> + <g style="fill: #ec9961"> + <path d="M136.128 28.837C129.728 29.637 104.999 5.605 119.328 37.637C136.128 75.193 60.394 76.482 44.128 65.637C27.328 54.437 51.328 84.037 51.328 84.037C69.728 104.037 35.328 87.237 35.328 87.237C0.928 74.437 -23.072 100.037 -26.272 100.837C-29.472 101.637 -34.272 104.837 -35.072 98.437C-35.872 92.037 -42.989 75.839 -75.073 101.637C-98.782 120.474 -111.655 100.11 -111.655 100.11L-115.655 107.237C-137.455 70.437 -124.236 128.765 -124.236 128.765C-115.436 163.165 16.128 121.637 16.128 121.637C16.128 121.637 184.928 91.237 196.129 87.237C207.329 83.237 299.911 89.419 299.911 89.419L294.529 71.092C229.729 24.691 212.929 49.637 199.329 45.637C185.728 41.637 188.128 51.237 184.928 52.037C181.728 52.837 142.528 28.037 136.128 28.837z"/> + </g> + <g style="fill: #eea575"> + <path d="M137.438 30.583C131.037 31.383 106.814 7.129 120.637 39.383C137.438 78.583 62.237 78.583 45.437 67.383C28.637 56.183 52.637 85.783 52.637 85.783C71.037 105.783 36.637 88.983 36.637 88.983C2.237 76.183 -21.763 101.783 -24.963 102.583C-28.163 103.383 -32.963 106.583 -33.763 100.183C-34.563 93.783 -41.548 77.752 -73.763 103.383C-98.709 122.965 -111.273 103.146 -111.273 103.146L-115.673 108.783C-135.473 73.982 -123.582 131.819 -123.582 131.819C-114.782 166.22 17.437 123.383 17.437 123.383C17.437 123.383 186.238 92.983 197.438 88.983C208.638 84.983 300.347 91.092 300.347 91.092L295.038 72.255C230.238 25.855 214.238 51.383 200.638 47.383C187.038 43.383 189.438 52.983 186.238 53.783C183.038 54.583 143.838 29.783 137.438 30.583z"/> + </g> + <g style="fill: #f1b288"> + <path d="M138.747 32.328C132.347 33.128 106.383 9.677 121.947 41.128C141.147 79.928 63.546 80.328 46.746 69.128C29.946 57.928 53.946 87.528 53.946 87.528C72.346 107.528 37.946 90.728 37.946 90.728C3.546 77.928 -20.454 103.528 -23.654 104.328C-26.854 105.128 -31.654 108.328 -32.454 101.928C-33.254 95.528 -40.108 79.665 -72.454 105.128C-98.636 125.456 -110.891 106.183 -110.891 106.183L-115.691 110.328C-133.691 77.128 -122.927 134.874 -122.927 134.874C-114.127 169.274 18.746 125.128 18.746 125.128C18.746 125.128 187.547 94.728 198.747 90.728C209.947 86.728 300.783 92.764 300.783 92.764L295.547 73.419C230.747 27.019 215.547 53.128 201.947 49.128C188.347 45.128 190.747 54.728 187.547 55.528C184.347 56.328 145.147 31.528 138.747 32.328z"/> + </g> + <g style="fill: #f3bf9c"> + <path d="M140.056 34.073C133.655 34.873 107.313 11.613 123.255 42.873C143.656 82.874 64.855 82.074 48.055 70.874C31.255 59.674 55.255 89.274 55.255 89.274C73.655 109.274 39.255 92.474 39.255 92.474C4.855 79.674 -19.145 105.274 -22.345 106.074C-25.545 106.874 -30.345 110.074 -31.145 103.674C-31.945 97.274 -38.668 81.578 -71.145 106.874C-98.564 127.947 -110.509 109.219 -110.509 109.219L-115.709 111.874C-131.709 81.674 -122.273 137.929 -122.273 137.929C-113.473 172.329 20.055 126.874 20.055 126.874C20.055 126.874 188.856 96.474 200.056 92.474C211.256 88.474 301.22 94.437 301.22 94.437L296.056 74.583C231.256 28.183 216.856 54.874 203.256 50.874C189.656 46.873 192.056 56.474 188.856 57.274C185.656 58.074 146.456 33.273 140.056 34.073z"/> + </g> + <g style="fill: #f5ccb0"> + <path d="M141.365 35.819C134.965 36.619 107.523 13.944 124.565 44.619C146.565 84.219 66.164 83.819 49.364 72.619C32.564 61.419 56.564 91.019 56.564 91.019C74.964 111.019 40.564 94.219 40.564 94.219C6.164 81.419 -17.836 107.019 -21.036 107.819C-24.236 108.619 -29.036 111.819 -29.836 105.419C-30.636 99.019 -37.227 83.492 -69.836 108.619C-98.491 130.438 -110.127 112.256 -110.127 112.256L-115.727 113.419C-130.128 85.019 -121.618 140.983 -121.618 140.983C-112.818 175.384 21.364 128.619 21.364 128.619C21.364 128.619 190.165 98.219 201.365 94.219C212.565 90.219 301.656 96.11 301.656 96.11L296.565 75.746C231.765 29.346 218.165 56.619 204.565 52.619C190.965 48.619 193.365 58.219 190.165 59.019C186.965 59.819 147.765 35.019 141.365 35.819z"/> + </g> + <g style="fill: #f8d8c4"> + <path d="M142.674 37.565C136.274 38.365 108.832 15.689 125.874 46.365C147.874 85.965 67.474 85.565 50.674 74.365C33.874 63.165 57.874 92.765 57.874 92.765C76.274 112.765 41.874 95.965 41.874 95.965C7.473 83.165 -16.527 108.765 -19.727 109.565C-22.927 110.365 -27.727 113.565 -28.527 107.165C-29.327 100.765 -35.786 85.405 -68.527 110.365C-98.418 132.929 -109.745 115.293 -109.745 115.293L-115.745 114.965C-129.346 88.564 -120.963 144.038 -120.963 144.038C-112.163 178.438 22.673 130.365 22.673 130.365C22.673 130.365 191.474 99.965 202.674 95.965C213.874 91.965 302.093 97.783 302.093 97.783L297.075 76.91C232.274 30.51 219.474 58.365 205.874 54.365C192.274 50.365 194.674 59.965 191.474 60.765C188.274 61.565 149.074 36.765 142.674 37.565z"/> + </g> + <g style="fill: #fae5d7"> + <path d="M143.983 39.31C137.583 40.11 110.529 17.223 127.183 48.11C149.183 88.91 68.783 87.31 51.983 76.11C35.183 64.91 59.183 94.51 59.183 94.51C77.583 114.51 43.183 97.71 43.183 97.71C8.783 84.91 -15.217 110.51 -18.417 111.31C-21.618 112.11 -26.418 115.31 -27.218 108.91C-28.018 102.51 -34.346 87.318 -67.218 112.11C-98.345 135.42 -109.363 118.329 -109.363 118.329L-115.764 116.51C-128.764 92.51 -120.309 147.093 -120.309 147.093C-111.509 181.493 23.983 132.11 23.983 132.11C23.983 132.11 192.783 101.71 203.983 97.71C215.183 93.71 302.529 99.456 302.529 99.456L297.583 78.074C232.783 31.673 220.783 60.11 207.183 56.11C193.583 52.11 195.983 61.71 192.783 62.51C189.583 63.31 150.383 38.51 143.983 39.31z"/> + </g> + <g style="fill: #fcf2eb"> + <path d="M145.292 41.055C138.892 41.855 112.917 18.411 128.492 49.855C149.692 92.656 70.092 89.056 53.292 77.856C36.492 66.656 60.492 96.256 60.492 96.256C78.892 116.256 44.492 99.456 44.492 99.456C10.092 86.656 -13.908 112.256 -17.108 113.056C-20.308 113.856 -25.108 117.056 -25.908 110.656C-26.708 104.256 -32.905 89.232 -65.908 113.856C-98.273 137.911 -108.982 121.365 -108.982 121.365L-115.782 118.056C-128.582 94.856 -119.654 150.147 -119.654 150.147C-110.854 184.547 25.292 133.856 25.292 133.856C25.292 133.856 194.093 103.456 205.293 99.456C216.493 95.456 302.965 101.128 302.965 101.128L298.093 79.237C233.292 32.837 222.093 61.856 208.493 57.856C194.893 53.855 197.293 63.456 194.093 64.256C190.892 65.056 151.692 40.255 145.292 41.055z"/> + </g> + <g style="fill: #ffffff"> + <path d="M-115.8 119.601C-128.6 97.6 -119 153.201 -119 153.201C-110.2 187.601 26.6 135.601 26.6 135.601C26.6 135.601 195.401 105.2 206.601 101.2C217.801 97.2 303.401 102.8 303.401 102.8L298.601 80.4C233.801 34 223.401 63.6 209.801 59.6C196.201 55.6 198.601 65.2 195.401 66C192.201 66.8 153.001 42 146.601 42.8C140.201 43.6 114.981 19.793 129.801 51.6C152.028 99.307 69.041 89.227 54.6 79.6C37.8 68.4 61.8 98 61.8 98C80.2 118.001 45.8 101.2 45.8 101.2C11.4 88.4 -12.6 114.001 -15.8 114.801C-19 115.601 -23.8 118.801 -24.6 112.401C-25.4 106 -31.465 91.144 -64.6 115.601C-98.2 140.401 -108.6 124.401 -108.6 124.401L-115.8 119.601z"/> + </g> + <g style="fill: #000000"> + <path d="M-74.2 149.601C-74.2 149.601 -81.4 161.201 -60.6 174.401C-60.6 174.401 -59.2 175.801 -77.2 171.601C-77.2 171.601 -83.4 169.601 -85 159.201C-85 159.201 -89.8 154.801 -94.6 149.201C-99.4 143.601 -74.2 149.601 -74.2 149.601z"/> + </g> + <g style="fill: #cccccc"> + <path d="M65.8 102C65.8 102 83.498 128.821 82.9 133.601C81.6 144.001 81.4 153.601 84.6 157.601C87.801 161.601 96.601 194.801 96.601 194.801C96.601 194.801 96.201 196.001 108.601 158.001C108.601 158.001 120.201 142.001 100.201 123.601C100.201 123.601 65 94.8 65.8 102z"/> + </g> + <g style="fill: #000000"> + <path d="M-54.2 176.401C-54.2 176.401 -43 183.601 -57.4 214.801L-51 212.401C-51 212.401 -51.8 223.601 -55 226.001L-47.8 222.801C-47.8 222.801 -43 230.801 -47 235.601C-47 235.601 -30.2 243.601 -31 250.001C-31 250.001 -24.6 242.001 -28.6 235.601C-32.6 229.201 -39.8 233.201 -39 214.801L-47.8 218.001C-47.8 218.001 -42.2 209.201 -42.2 202.801L-50.2 205.201C-50.2 205.201 -34.731 178.623 -45.4 177.201C-51.4 176.401 -54.2 176.401 -54.2 176.401z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-21.8 193.201C-21.8 193.201 -19 188.801 -21.8 189.601C-24.6 190.401 -55.8 205.201 -61.8 214.801C-61.8 214.801 -27.4 190.401 -21.8 193.201z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-11.4 201.201C-11.4 201.201 -8.6 196.801 -11.4 197.601C-14.2 198.401 -45.4 213.201 -51.4 222.801C-51.4 222.801 -17 198.401 -11.4 201.201z"/> + </g> + <g style="fill: #cccccc"> + <path d="M1.8 186.001C1.8 186.001 4.6 181.601 1.8 182.401C-1 183.201 -32.2 198.001 -38.2 207.601C-38.2 207.601 -3.8 183.201 1.8 186.001z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-21.4 229.601C-21.4 229.601 -21.4 223.601 -24.2 224.401C-27 225.201 -63 242.801 -69 252.401C-69 252.401 -27 226.801 -21.4 229.601z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-20.2 218.801C-20.2 218.801 -19 214.001 -21.8 214.801C-23.8 214.801 -50.2 226.401 -56.2 236.001C-56.2 236.001 -26.6 214.401 -20.2 218.801z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-34.6 266.401L-44.6 274.001C-44.6 274.001 -34.2 266.401 -30.6 267.601C-30.6 267.601 -37.4 278.801 -38.2 284.001C-38.2 284.001 -27.8 271.201 -22.2 271.601C-22.2 271.601 -14.6 272.001 -14.6 282.801C-14.6 282.801 -9 272.401 -5.8 272.801C-5.8 272.801 -4.6 279.201 -5.8 286.001C-5.8 286.001 -1.8 278.401 2.2 280.001C2.2 280.001 8.6 278.001 7.8 289.601C7.8 289.601 7.8 300.001 7 302.801C7 302.801 12.6 276.401 15 276.001C15 276.001 23 274.801 27.8 283.601C27.8 283.601 23.8 276.001 28.6 278.001C28.6 278.001 39.4 279.601 42.6 286.401C42.6 286.401 35.8 274.401 41.4 277.601C41.4 277.601 48.2 277.601 49.4 284.001C49.4 284.001 57.8 305.201 59.8 306.801C59.8 306.801 52.2 285.201 53.8 285.201C53.8 285.201 51.8 273.201 57 288.001C57 288.001 53.8 274.001 59.4 274.801C65 275.601 69.4 285.601 77.8 283.201C77.8 283.201 87.401 288.801 89.401 219.601L-34.6 266.401z"/> + </g> + <g style="fill: #000000"> + <path d="M-29.8 173.601C-29.8 173.601 -15 167.601 25 173.601C25 173.601 32.2 174.001 39 165.201C45.8 156.401 72.6 149.201 79 151.201L88.601 157.601L89.401 158.801C89.401 158.801 101.801 169.201 102.201 176.801C102.601 184.401 87.801 232.401 78.2 248.401C68.6 264.401 59 276.801 39.8 274.401C39.8 274.401 19 270.401 -6.6 274.401C-6.6 274.401 -35.8 272.801 -38.6 264.801C-41.4 256.801 -27.4 241.601 -27.4 241.601C-27.4 241.601 -23 233.201 -24.2 218.801C-25.4 204.401 -25 176.401 -29.8 173.601z"/> + </g> + <g style="fill: #e5668c"> + <path d="M-7.8 175.601C0.6 194.001 -29 259.201 -29 259.201C-31 260.801 -16.34 266.846 -6.2 264.401C4.746 261.763 45 266.001 45 266.001C68.6 250.401 81.4 206.001 81.4 206.001C81.4 206.001 91.801 182.001 74.2 178.801C56.6 175.601 -7.8 175.601 -7.8 175.601z"/> + </g> + <g style="fill: #b23259"> + <path d="M-9.831 206.497C-6.505 193.707 -4.921 181.906 -7.8 175.601C-7.8 175.601 54.6 182.001 65.8 161.201C70.041 153.326 84.801 184.001 84.4 193.601C84.4 193.601 21.4 208.001 6.6 196.801L-9.831 206.497z"/> + </g> + <g style="fill: #a5264c"> + <path d="M-5.4 222.801C-5.4 222.801 -3.4 230.001 -5.8 234.001C-5.8 234.001 -7.4 234.801 -8.6 235.201C-8.6 235.201 -7.4 238.801 -1.4 240.401C-1.4 240.401 0.6 244.801 3 245.201C5.4 245.601 10.2 251.201 14.2 250.001C18.2 248.801 29.4 244.801 29.4 244.801C29.4 244.801 35 241.601 43.8 245.201C43.8 245.201 46.175 244.399 46.6 240.401C47.1 235.701 50.2 232.001 52.2 230.001C54.2 228.001 63.8 215.201 62.6 214.801C61.4 214.401 -5.4 222.801 -5.4 222.801z"/> + </g> + <g style="fill: #ff727f; stroke:#000000"> + <path d="M-9.8 174.401C-9.8 174.401 -12.6 196.801 -9.4 205.201C-6.2 213.601 -7 215.601 -7.8 219.601C-8.6 223.601 -4.2 233.601 1.4 239.601L13.4 241.201C13.4 241.201 28.6 237.601 37.8 240.401C37.8 240.401 46.794 241.744 50.2 226.801C50.2 226.801 55 220.401 62.2 217.601C69.4 214.801 76.6 173.201 72.6 165.201C68.6 157.201 54.2 152.801 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-8.2 249.201C-8.2 249.201 -9 247.201 -13.4 246.801C-13.4 246.801 -35.8 243.201 -44.2 230.801C-44.2 230.801 -51 225.201 -46.6 236.801C-46.6 236.801 -36.2 257.201 -29.4 260.001C-29.4 260.001 -13 264.001 -8.2 249.201z"/> + </g> + <g style="fill: #cc3f4c"> + <path d="M71.742 185.229C72.401 177.323 74.354 168.709 72.6 165.201C66.154 152.307 49.181 157.695 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401C-9.8 174.401 -11.545 188.364 -10.705 198.376C-10.705 198.376 26.6 186.801 27.4 192.401C27.4 192.401 29 189.201 38.2 189.201C47.4 189.201 70.142 188.029 71.742 185.229z"/> + </g> + <g style="stroke:#a51926; stroke-width:2"> + <path d="M28.6 175.201C28.6 175.201 33.4 180.001 29.8 189.601C29.8 189.601 15.4 205.601 17.4 219.601"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-19.4 260.001C-19.4 260.001 -23.8 247.201 -15 254.001C-15 254.001 -10.2 256.001 -11.4 257.601C-12.6 259.201 -18.2 263.201 -19.4 260.001z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-14.36 261.201C-14.36 261.201 -17.88 250.961 -10.84 256.401C-10.84 256.401 -6.419 258.849 -7.96 259.281C-12.52 260.561 -7.96 263.121 -14.36 261.201z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-9.56 261.201C-9.56 261.201 -13.08 250.961 -6.04 256.401C-6.04 256.401 -1.665 258.711 -3.16 259.281C-6.52 260.561 -3.16 263.121 -9.56 261.201z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-2.96 261.401C-2.96 261.401 -6.48 251.161 0.56 256.601C0.56 256.601 4.943 258.933 3.441 259.481C0.48 260.561 3.441 263.321 -2.96 261.401z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M3.52 261.321C3.52 261.321 0 251.081 7.041 256.521C7.041 256.521 10.881 258.121 9.921 259.401C8.961 260.681 9.921 263.241 3.52 261.321z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M10.2 262.001C10.2 262.001 5.4 249.601 14.6 256.001C14.6 256.001 19.4 258.001 18.2 259.601C17 261.201 18.2 264.401 10.2 262.001z"/> + </g> + <g style="stroke:#a5264c; stroke-width:2"> + <path d="M-18.2 244.801C-18.2 244.801 -5 242.001 1 245.201C1 245.201 7 246.401 8.2 246.001C9.4 245.601 12.6 245.201 12.6 245.201"/> + </g> + <g style="stroke:#a5264c; stroke-width:2"> + <path d="M15.8 253.601C15.8 253.601 27.8 240.001 39.8 244.401C46.816 246.974 45.8 243.601 46.6 240.801C47.4 238.001 47.6 233.801 52.6 230.801"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M33 237.601C33 237.601 29 226.801 26.2 239.601C23.4 252.401 20.2 256.001 18.6 258.801C18.6 258.801 18.6 264.001 27 263.601C27 263.601 37.8 263.201 38.2 260.401C38.6 257.601 37 246.001 33 237.601z"/> + </g> + <g style="stroke:#a5264c; stroke-width:2"> + <path d="M47 244.801C47 244.801 50.6 242.401 53 243.601"/> + </g> + <g style="stroke:#a5264c; stroke-width:2"> + <path d="M53.5 228.401C53.5 228.401 56.4 223.501 61.2 222.701"/> + </g> + <g style="fill: #b2b2b2"> + <path d="M-25.8 265.201C-25.8 265.201 -7.8 268.401 -3.4 266.801C-3.4 266.801 5.4 266.801 -3 268.801C-3 268.801 -15.8 268.801 -23.8 267.601C-23.8 267.601 -35.4 262.001 -25.8 265.201z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-11.8 172.001C-11.8 172.001 5.8 172.001 7.8 172.801C7.8 172.801 15 203.601 11.4 211.201C11.4 211.201 10.2 214.001 7.4 208.401C7.4 208.401 -11 175.601 -14.2 173.601C-17.4 171.601 -13 172.001 -11.8 172.001z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-88.9 169.301C-88.9 169.301 -80 171.001 -67.4 173.601C-67.4 173.601 -62.6 196.001 -59.4 200.801C-56.2 205.601 -59.8 205.601 -63.4 202.801C-67 200.001 -81.8 186.001 -83.8 181.601C-85.8 177.201 -88.9 169.301 -88.9 169.301z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-67.039 173.818C-67.039 173.818 -61.239 175.366 -60.23 177.581C-59.222 179.795 -61.432 183.092 -61.432 183.092C-61.432 183.092 -62.432 186.397 -63.634 184.235C-64.836 182.072 -67.708 174.412 -67.039 173.818z"/> + </g> + <g style="fill: #000000"> + <path d="M-67 173.601C-67 173.601 -63.4 178.801 -59.8 178.801C-56.2 178.801 -55.818 178.388 -53 179.001C-48.4 180.001 -48.8 178.001 -42.2 179.201C-39.56 179.681 -37 178.801 -34.2 180.001C-31.4 181.201 -28.2 180.401 -27 178.401C-25.8 176.401 -21 172.201 -21 172.201C-21 172.201 -33.8 174.001 -36.6 174.801C-36.6 174.801 -59 176.001 -67 173.601z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-22.4 173.801C-22.4 173.801 -28.85 177.301 -29.25 179.701C-29.65 182.101 -24 185.801 -24 185.801C-24 185.801 -21.25 190.401 -20.65 188.001C-20.05 185.601 -21.6 174.201 -22.4 173.801z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-59.885 179.265C-59.885 179.265 -52.878 190.453 -52.661 179.242C-52.661 179.242 -52.104 177.984 -53.864 177.962C-59.939 177.886 -58.418 173.784 -59.885 179.265z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-52.707 179.514C-52.707 179.514 -44.786 190.701 -45.422 179.421C-45.422 179.421 -45.415 179.089 -47.168 178.936C-51.915 178.522 -51.57 174.004 -52.707 179.514z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-45.494 179.522C-45.494 179.522 -37.534 190.15 -38.203 180.484C-38.203 180.484 -38.084 179.251 -39.738 178.95C-43.63 178.244 -43.841 174.995 -45.494 179.522z"/> + </g> + <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5"> + <path d="M-38.618 179.602C-38.618 179.602 -30.718 191.163 -30.37 181.382C-30.37 181.382 -28.726 180.004 -30.472 179.782C-36.29 179.042 -35.492 174.588 -38.618 179.602z"/> + </g> + <g style="fill: #e5e5b2"> + <path d="M-74.792 183.132L-82.45 181.601C-85.05 176.601 -87.15 170.451 -87.15 170.451C-87.15 170.451 -80.8 171.451 -68.3 174.251C-68.3 174.251 -67.424 177.569 -65.952 183.364L-74.792 183.132z"/> + </g> + <g style="fill: #e5e5b2"> + <path d="M-9.724 178.47C-11.39 175.964 -12.707 174.206 -13.357 173.8C-16.37 171.917 -12.227 172.294 -11.098 172.294C-11.098 172.294 5.473 172.294 7.356 173.047C7.356 173.047 7.88 175.289 8.564 178.68C8.564 178.68 -1.524 176.67 -9.724 178.47z"/> + </g> + <g style="fill: #cc7226"> + <path d="M43.88 40.321C71.601 44.281 97.121 8.641 98.881 -1.04C100.641 -10.72 90.521 -22.6 90.521 -22.6C91.841 -25.68 87.001 -39.76 81.721 -49C76.441 -58.24 60.54 -57.266 43 -58.24C27.16 -59.12 8.68 -35.8 7.36 -34.04C6.04 -32.28 12.2 6.001 13.52 11.721C14.84 17.441 12.2 43.841 12.2 43.841C46.44 34.741 16.16 36.361 43.88 40.321z"/> + </g> + <g style="fill: #ea8e51"> + <path d="M8.088 -33.392C6.792 -31.664 12.84 5.921 14.136 11.537C15.432 17.153 12.84 43.073 12.84 43.073C45.512 34.193 16.728 35.729 43.944 39.617C71.161 43.505 96.217 8.513 97.945 -0.992C99.673 -10.496 89.737 -22.16 89.737 -22.16C91.033 -25.184 86.281 -39.008 81.097 -48.08C75.913 -57.152 60.302 -56.195 43.08 -57.152C27.528 -58.016 9.384 -35.12 8.088 -33.392z"/> + </g> + <g style="fill: #efaa7c"> + <path d="M8.816 -32.744C7.544 -31.048 13.48 5.841 14.752 11.353C16.024 16.865 13.48 42.305 13.48 42.305C44.884 33.145 17.296 35.097 44.008 38.913C70.721 42.729 95.313 8.385 97.009 -0.944C98.705 -10.272 88.953 -21.72 88.953 -21.72C90.225 -24.688 85.561 -38.256 80.473 -47.16C75.385 -56.064 60.063 -55.125 43.16 -56.064C27.896 -56.912 10.088 -34.44 8.816 -32.744z"/> + </g> + <g style="fill: #f4c6a8"> + <path d="M9.544 -32.096C8.296 -30.432 14.12 5.761 15.368 11.169C16.616 16.577 14.12 41.537 14.12 41.537C43.556 32.497 17.864 34.465 44.072 38.209C70.281 41.953 94.409 8.257 96.073 -0.895C97.737 -10.048 88.169 -21.28 88.169 -21.28C89.417 -24.192 84.841 -37.504 79.849 -46.24C74.857 -54.976 59.824 -54.055 43.24 -54.976C28.264 -55.808 10.792 -33.76 9.544 -32.096z"/> + </g> + <g style="fill: #f9e2d3"> + <path d="M10.272 -31.448C9.048 -29.816 14.76 5.681 15.984 10.985C17.208 16.289 14.76 40.769 14.76 40.769C42.628 31.849 18.432 33.833 44.136 37.505C69.841 41.177 93.505 8.129 95.137 -0.848C96.769 -9.824 87.385 -20.84 87.385 -20.84C88.609 -23.696 84.121 -36.752 79.225 -45.32C74.329 -53.888 59.585 -52.985 43.32 -53.888C28.632 -54.704 11.496 -33.08 10.272 -31.448z"/> + </g> + <g style="fill: #ffffff"> + <path d="M44.2 36.8C69.4 40.4 92.601 8 94.201 -0.8C95.801 -9.6 86.601 -20.4 86.601 -20.4C87.801 -23.2 83.4 -36 78.6 -44.4C73.8 -52.8 59.346 -51.914 43.4 -52.8C29 -53.6 12.2 -32.4 11 -30.8C9.8 -29.2 15.4 5.6 16.6 10.8C17.8 16 15.4 40 15.4 40C40.9 31.4 19 33.2 44.2 36.8z"/> + </g> + <g style="fill: #cccccc"> + <path d="M90.601 2.8C90.601 2.8 62.8 10.4 51.2 8.8C51.2 8.8 35.4 2.2 26.6 24C26.6 24 23 31.2 21 33.2C19 35.2 90.601 2.8 90.601 2.8z"/> + </g> + <g style="fill: #000000"> + <path d="M94.401 0.6C94.401 0.6 65.4 12.8 55.4 12.4C55.4 12.4 39 7.8 30.6 22.4C30.6 22.4 22.2 31.6 19 33.2C19 33.2 18.6 34.8 25 30.8L35.4 36C35.4 36 50.2 45.6 59.8 29.6C59.8 29.6 63.8 18.4 63.8 16.4C63.8 14.4 85 8.8 86.601 8.4C88.201 8 94.801 3.8 94.401 0.6z"/> + </g> + <g style="fill: #99cc32"> + <path d="M47 36.514C40.128 36.514 31.755 32.649 31.755 26.4C31.755 20.152 40.128 13.887 47 13.887C53.874 13.887 59.446 18.952 59.446 25.2C59.446 31.449 53.874 36.514 47 36.514z"/> + </g> + <g style="fill: #659900"> + <path d="M43.377 19.83C38.531 20.552 33.442 22.055 33.514 21.839C35.054 17.22 41.415 13.887 47 13.887C51.296 13.887 55.084 15.865 57.32 18.875C57.32 18.875 52.004 18.545 43.377 19.83z"/> + </g> + <g style="fill: #ffffff"> + <path d="M55.4 19.6C55.4 19.6 51 16.4 51 18.6C51 18.6 54.6 23 55.4 19.6z"/> + </g> + <g style="fill: #000000"> + <path d="M45.4 27.726C42.901 27.726 40.875 25.7 40.875 23.2C40.875 20.701 42.901 18.675 45.4 18.675C47.9 18.675 49.926 20.701 49.926 23.2C49.926 25.7 47.9 27.726 45.4 27.726z"/> + </g> + <g style="fill: #cc7226"> + <path d="M-58.6 14.4C-58.6 14.4 -61.8 -6.8 -59.4 -11.2C-59.4 -11.2 -48.6 -21.2 -49 -24.8C-49 -24.8 -49.4 -42.8 -50.6 -43.6C-51.8 -44.4 -59.4 -50.4 -65.4 -44C-65.4 -44 -75.8 -26 -75 -19.6L-75 -17.6C-75 -17.6 -82.6 -18 -84.2 -16C-84.2 -16 -85.4 -10.8 -86.6 -10.4C-86.6 -10.4 -89.4 -8 -87.4 -5.2C-87.4 -5.2 -89.4 -2.8 -89 1.2L-81.4 5.2C-81.4 5.2 -79.4 19.6 -68.6 24.8C-63.764 27.129 -60.6 20.4 -58.6 14.4z"/> + </g> + <g style="fill: #ffffff"> + <path d="M-59.6 12.56C-59.6 12.56 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.48 -40.36 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.96 -59.6 12.56z"/> + </g> + <g style="fill: #eb955c"> + <path d="M-51.05 -42.61C-52.14 -43.47 -59.63 -49.24 -65.48 -43C-65.48 -43 -75.62 -25.45 -74.84 -19.21L-74.84 -17.26C-74.84 -17.26 -82.25 -17.65 -83.81 -15.7C-83.81 -15.7 -84.98 -10.63 -86.15 -10.24C-86.15 -10.24 -88.88 -7.9 -86.93 -5.17C-86.93 -5.17 -88.88 -2.83 -88.49 1.07L-81.08 4.97C-81.08 4.97 -79.13 19.01 -68.6 24.08C-63.886 26.35 -60.8 19.79 -58.85 13.94C-58.85 13.94 -61.97 -6.73 -59.63 -11.02C-59.63 -11.02 -49.1 -20.77 -49.49 -24.28C-49.49 -24.28 -49.88 -41.83 -51.05 -42.61z"/> + </g> + <g style="fill: #f2b892"> + <path d="M-51.5 -41.62C-52.48 -42.54 -59.86 -48.08 -65.56 -42C-65.56 -42 -75.44 -24.9 -74.68 -18.82L-74.68 -16.92C-74.68 -16.92 -81.9 -17.3 -83.42 -15.4C-83.42 -15.4 -84.56 -10.46 -85.7 -10.08C-85.7 -10.08 -88.36 -7.8 -86.46 -5.14C-86.46 -5.14 -88.36 -2.86 -87.98 0.94L-80.76 4.74C-80.76 4.74 -78.86 18.42 -68.6 23.36C-64.006 25.572 -61 19.18 -59.1 13.48C-59.1 13.48 -62.14 -6.66 -59.86 -10.84C-59.86 -10.84 -49.6 -20.34 -49.98 -23.76C-49.98 -23.76 -50.36 -40.86 -51.5 -41.62z"/> + </g> + <g style="fill: #f8dcc8"> + <path d="M-51.95 -40.63C-52.82 -41.61 -60.09 -46.92 -65.64 -41C-65.64 -41 -75.26 -24.35 -74.52 -18.43L-74.52 -16.58C-74.52 -16.58 -81.55 -16.95 -83.03 -15.1C-83.03 -15.1 -84.14 -10.29 -85.25 -9.92C-85.25 -9.92 -87.84 -7.7 -85.99 -5.11C-85.99 -5.11 -87.84 -2.89 -87.47 0.81L-80.44 4.51C-80.44 4.51 -78.59 17.83 -68.6 22.64C-64.127 24.794 -61.2 18.57 -59.35 13.02C-59.35 13.02 -62.31 -6.59 -60.09 -10.66C-60.09 -10.66 -50.1 -19.91 -50.47 -23.24C-50.47 -23.24 -50.84 -39.89 -51.95 -40.63z"/> + </g> + <g style="fill: #ffffff"> + <path d="M-59.6 12.46C-59.6 12.46 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.16 -40.68 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.86 -59.6 12.46z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-62.7 6.2C-62.7 6.2 -84.3 -4 -85.2 -4.8C-85.2 -4.8 -76.1 3.4 -75.3 3.4C-74.5 3.4 -62.7 6.2 -62.7 6.2z"/> + </g> + <g style="fill: #000000"> + <path d="M-79.8 0C-79.8 0 -61.4 3.6 -61.4 8C-61.4 10.912 -61.643 24.331 -67 22.8C-75.4 20.4 -71.8 6 -79.8 0z"/> + </g> + <g style="fill: #99cc32"> + <path d="M-71.4 3.8C-71.4 3.8 -62.422 5.274 -61.4 8C-60.8 9.6 -60.137 17.908 -65.6 19C-70.152 19.911 -72.382 9.69 -71.4 3.8z"/> + </g> + <g style="fill: #000000"> + <path d="M14.595 46.349C14.098 44.607 15.409 44.738 17.2 44.2C19.2 43.6 31.4 39.8 32.2 37.2C33 34.6 46.2 39 46.2 39C48 39.8 52.4 42.4 52.4 42.4C57.2 43.6 63.8 44 63.8 44C66.2 45 69.6 47.8 69.6 47.8C84.2 58 96.601 50.8 96.601 50.8C116.601 44.2 110.601 27 110.601 27C107.601 18 110.801 14.6 110.801 14.6C111.001 10.8 118.201 17.2 118.201 17.2C120.801 21.4 121.601 26.4 121.601 26.4C129.601 37.6 126.201 19.8 126.201 19.8C126.401 18.8 123.601 15.2 123.601 14C123.601 12.8 121.801 9.4 121.801 9.4C118.801 6 121.201 -1 121.201 -1C123.001 -14.8 120.801 -13 120.801 -13C119.601 -14.8 110.401 -4.8 110.401 -4.8C108.201 -1.4 102.201 0.2 102.201 0.2C99.401 2 96.001 0.6 96.001 0.6C93.401 0.2 87.801 7.2 87.801 7.2C90.601 7 93.001 11.4 95.401 11.6C97.801 11.8 99.601 9.2 101.201 8.6C102.801 8 105.601 13.8 105.601 13.8C106.001 16.4 100.401 21.2 100.401 21.2C100.001 25.8 98.401 24.2 98.401 24.2C95.401 23.6 94.201 27.4 93.201 32C92.201 36.6 88.001 37 88.001 37C86.401 44.4 85.2 41.4 85.2 41.4C85 35.8 79 41.6 79 41.6C77.8 43.6 73.2 41.4 73.2 41.4C66.4 39.4 68.8 37.4 68.8 37.4C70.6 35.2 81.8 37.4 81.8 37.4C84 35.8 76 31.8 76 31.8C75.4 30 76.4 25.6 76.4 25.6C77.6 22.4 84.4 16.8 84.4 16.8C93.801 15.6 91.001 14 91.001 14C84.801 8.8 79 16.4 79 16.4C76.8 22.6 59.4 37.6 59.4 37.6C54.6 41 57.2 34.2 53.2 37.6C49.2 41 28.6 32 28.6 32C17.038 30.807 14.306 46.549 10.777 43.429C10.777 43.429 16.195 51.949 14.595 46.349z"/> + </g> + <g style="fill: #000000"> + <path d="M209.401 -120C209.401 -120 183.801 -112 181.001 -93.2C181.001 -93.2 178.601 -70.4 199.001 -52.8C199.001 -52.8 199.401 -46.4 201.401 -43.2C201.401 -43.2 199.801 -38.4 218.601 -46L245.801 -54.4C245.801 -54.4 252.201 -56.8 257.401 -65.6C262.601 -74.4 277.801 -93.2 274.201 -118.4C274.201 -118.4 275.401 -129.6 269.401 -130C269.401 -130 261.001 -131.6 253.801 -124C253.801 -124 247.001 -120.8 244.601 -121.2L209.401 -120z"/> + </g> + <g style="fill: #000000"> + <path d="M264.022 -120.99C264.022 -120.99 266.122 -129.92 261.282 -125.08C261.282 -125.08 254.242 -119.36 246.761 -119.36C246.761 -119.36 232.241 -117.16 227.841 -103.96C227.841 -103.96 223.881 -77.12 231.801 -71.4C231.801 -71.4 236.641 -63.92 243.681 -70.52C250.722 -77.12 266.222 -107.35 264.022 -120.99z"/> + </g> + <g style="fill: #323232"> + <path d="M263.648 -120.632C263.648 -120.632 265.738 -129.376 260.986 -124.624C260.986 -124.624 254.074 -119.008 246.729 -119.008C246.729 -119.008 232.473 -116.848 228.153 -103.888C228.153 -103.888 224.265 -77.536 232.041 -71.92C232.041 -71.92 236.793 -64.576 243.705 -71.056C250.618 -77.536 265.808 -107.24 263.648 -120.632z"/> + </g> + <g style="fill: #666666"> + <path d="M263.274 -120.274C263.274 -120.274 265.354 -128.832 260.69 -124.168C260.69 -124.168 253.906 -118.656 246.697 -118.656C246.697 -118.656 232.705 -116.536 228.465 -103.816C228.465 -103.816 224.649 -77.952 232.281 -72.44C232.281 -72.44 236.945 -65.232 243.729 -71.592C250.514 -77.952 265.394 -107.13 263.274 -120.274z"/> + </g> + <g style="fill: #999999"> + <path d="M262.9 -119.916C262.9 -119.916 264.97 -128.288 260.394 -123.712C260.394 -123.712 253.738 -118.304 246.665 -118.304C246.665 -118.304 232.937 -116.224 228.777 -103.744C228.777 -103.744 225.033 -78.368 232.521 -72.96C232.521 -72.96 237.097 -65.888 243.753 -72.128C250.41 -78.368 264.98 -107.02 262.9 -119.916z"/> + </g> + <g style="fill: #cccccc"> + <path d="M262.526 -119.558C262.526 -119.558 264.586 -127.744 260.098 -123.256C260.098 -123.256 253.569 -117.952 246.633 -117.952C246.633 -117.952 233.169 -115.912 229.089 -103.672C229.089 -103.672 225.417 -78.784 232.761 -73.48C232.761 -73.48 237.249 -66.544 243.777 -72.664C250.305 -78.784 264.566 -106.91 262.526 -119.558z"/> + </g> + <g style="fill: #ffffff"> + <path d="M262.151 -119.2C262.151 -119.2 264.201 -127.2 259.801 -122.8C259.801 -122.8 253.401 -117.6 246.601 -117.6C246.601 -117.6 233.401 -115.6 229.401 -103.6C229.401 -103.6 225.801 -79.2 233.001 -74C233.001 -74 237.401 -67.2 243.801 -73.2C250.201 -79.2 264.151 -106.8 262.151 -119.2z"/> + </g> + <g style="fill: #992600"> + <path d="M50.6 84C50.6 84 30.2 64.8 22.2 64C22.2 64 -12.2 60 -27 78C-27 78 -9.4 57.6 18.2 63.2C18.2 63.2 -3.4 58.8 -15.8 62C-15.8 62 -32.6 62 -42.2 76L-45 80.8C-45 80.8 -41 66 -22.6 60C-22.6 60 0.2 55.2 11 60C11 60 -10.6 53.2 -20.6 55.2C-20.6 55.2 -51 52.8 -63.8 79.2C-63.8 79.2 -59.8 64.8 -45 57.6C-45 57.6 -31.4 48.8 -11 51.6C-11 51.6 3.4 54.8 8.6 57.2C13.8 59.6 12.6 56.8 4.2 52C4.2 52 -1.4 42 -15.4 42.4C-15.4 42.4 -58.2 46 -68.6 58C-68.6 58 -55 46.8 -44.6 44C-44.6 44 -22.2 36 -13.8 36.8C-13.8 36.8 11 37.8 18.6 33.8C18.6 33.8 7.4 38.8 10.6 42C13.8 45.2 20.6 52.8 20.6 54C20.6 55.2 44.8 77.3 48.4 81.7L50.6 84z"/> + </g> + <g style="fill: #cccccc"> + <path d="M189 278C189 278 173.5 241.5 161 232C161 232 187 248 190.5 266C190.5 266 190.5 276 189 278z"/> + </g> + <g style="fill: #cccccc"> + <path d="M236 285.5C236 285.5 209.5 230.5 191 206.5C191 206.5 234.5 244 239.5 270.5L240 276L237 273.5C237 273.5 236.5 282.5 236 285.5z"/> + </g> + <g style="fill: #cccccc"> + <path d="M292.5 237C292.5 237 230 177.5 228.5 175C228.5 175 289 241 292 248.5C292 248.5 290 239.5 292.5 237z"/> + </g> + <g style="fill: #cccccc"> + <path d="M104 280.5C104 280.5 123.5 228.5 142.5 251C142.5 251 157.5 261 157 264C157 264 153 257.5 135 258C135 258 116 255 104 280.5z"/> + </g> + <g style="fill: #cccccc"> + <path d="M294.5 153C294.5 153 249.5 124.5 242 123C230.193 120.639 291.5 152 296.5 162.5C296.5 162.5 298.5 160 294.5 153z"/> + </g> + <g style="fill: #000000"> + <path d="M143.801 259.601C143.801 259.601 164.201 257.601 171.001 250.801L175.401 254.401L193.001 216.001L196.601 221.201C196.601 221.201 211.001 206.401 210.201 198.401C209.401 190.401 223.001 204.401 223.001 204.401C223.001 204.401 222.201 192.801 229.401 199.601C229.401 199.601 227.001 184.001 235.401 192.001C235.401 192.001 224.864 161.844 247.401 187.601C253.001 194.001 248.601 187.201 248.601 187.201C248.601 187.201 222.601 139.201 244.201 153.601C244.201 153.601 246.201 130.801 245.001 126.401C243.801 122.001 241.801 99.6 237.001 94.4C232.201 89.2 237.401 87.6 243.001 92.8C243.001 92.8 231.801 68.8 245.001 80.8C245.001 80.8 241.401 65.6 237.001 62.8C237.001 62.8 231.401 45.6 246.601 56.4C246.601 56.4 242.201 44 239.001 40.8C239.001 40.8 227.401 13.2 234.601 18L239.001 21.6C239.001 21.6 232.201 7.6 238.601 12C245.001 16.4 245.001 16 245.001 16C245.001 16 223.801 -17.2 244.201 0.4C244.201 0.4 236.042 -13.518 232.601 -20.4C232.601 -20.4 213.801 -40.8 228.201 -34.4L233.001 -32.8C233.001 -32.8 224.201 -42.8 216.201 -44.4C208.201 -46 218.601 -52.4 225.001 -50.4C231.401 -48.4 247.001 -40.8 247.001 -40.8C247.001 -40.8 259.801 -22 263.801 -21.6C263.801 -21.6 243.801 -29.2 249.801 -21.2C249.801 -21.2 264.201 -7.2 257.001 -7.6C257.001 -7.6 251.001 -0.4 255.801 8.4C255.801 8.4 237.342 -9.991 252.201 15.6L259.001 32C259.001 32 234.601 7.2 245.801 29.2C245.801 29.2 263.001 52.8 265.001 53.2C267.001 53.6 271.401 62.4 271.401 62.4L267.001 60.4L272.201 69.2C272.201 69.2 261.001 57.2 267.001 70.4L272.601 84.8C272.601 84.8 252.201 62.8 265.801 92.4C265.801 92.4 249.401 87.2 258.201 104.4C258.201 104.4 256.601 120.401 257.001 125.601C257.401 130.801 258.601 159.201 254.201 167.201C249.801 175.201 260.201 194.401 262.201 198.401C264.201 202.401 267.801 213.201 259.001 204.001C250.201 194.801 254.601 200.401 256.601 209.201C258.601 218.001 264.601 233.601 263.801 239.201C263.801 239.201 262.601 240.401 259.401 236.801C259.401 236.801 244.601 214.001 246.201 228.401C246.201 228.401 245.001 236.401 241.801 245.201C241.801 245.201 238.601 256.001 238.601 247.201C238.601 247.201 235.401 230.401 232.601 238.001C229.801 245.601 226.201 251.601 223.401 254.001C220.601 256.401 215.401 233.601 214.201 244.001C214.201 244.001 202.201 231.601 197.401 248.001L185.801 264.401C185.801 264.401 185.401 252.001 184.201 258.001C184.201 258.001 154.201 264.001 143.801 259.601z"/> + </g> + <g style="fill: #000000"> + <path d="M109.401 -97.2C109.401 -97.2 97.801 -105.2 93.801 -104.8C89.801 -104.4 121.401 -113.6 162.601 -86C162.601 -86 167.401 -83.2 171.001 -83.6C171.001 -83.6 174.201 -81.2 171.401 -77.6C171.401 -77.6 162.601 -68 173.801 -56.8C173.801 -56.8 192.201 -50 186.601 -58.8C186.601 -58.8 197.401 -54.8 199.801 -50.8C202.201 -46.8 201.001 -50.8 201.001 -50.8C201.001 -50.8 194.601 -58 188.601 -63.2C188.601 -63.2 183.401 -65.2 180.601 -73.6C177.801 -82 175.401 -92 179.801 -95.2C179.801 -95.2 175.801 -90.8 176.601 -94.8C177.401 -98.8 181.001 -102.4 182.601 -102.8C184.201 -103.2 200.601 -119 207.401 -119.4C207.401 -119.4 198.201 -118 195.201 -119C192.201 -120 165.601 -131.4 159.601 -132.6C159.601 -132.6 142.801 -139.2 154.801 -137.2C154.801 -137.2 190.601 -133.4 208.801 -120.2C208.801 -120.2 201.601 -128.6 183.201 -135.6C183.201 -135.6 161.001 -148.2 125.801 -143.2C125.801 -143.2 108.001 -140 100.201 -138.2C100.201 -138.2 97.601 -138.8 97.001 -139.2C96.401 -139.6 84.6 -148.6 57 -141.6C57 -141.6 40 -137 31.4 -132.2C31.4 -132.2 16.2 -131 12.6 -127.8C12.6 -127.8 -6 -113.2 -8 -112.4C-10 -111.6 -21.4 -104 -22.2 -103.6C-22.2 -103.6 2.4 -110.2 4.8 -112.6C7.2 -115 24.6 -117.6 27 -116.2C29.4 -114.8 37.8 -115.4 28.2 -114.8C28.2 -114.8 103.801 -100 104.601 -98C105.401 -96 109.401 -97.2 109.401 -97.2z"/> + </g> + <g style="fill: #cc7226"> + <path d="M180.801 -106.4C180.801 -106.4 170.601 -113.8 168.601 -113.8C166.601 -113.8 154.201 -124 150.001 -123.6C145.801 -123.2 133.601 -133.2 106.201 -125C106.201 -125 105.601 -127 109.201 -127.8C109.201 -127.8 115.601 -130 116.001 -130.6C116.001 -130.6 136.201 -134.8 143.401 -131.2C143.401 -131.2 152.601 -128.6 158.801 -122.4C158.801 -122.4 170.001 -119.2 173.201 -120.2C173.201 -120.2 182.001 -118 182.401 -116.2C182.401 -116.2 188.201 -113.2 186.401 -110.6C186.401 -110.6 186.801 -109 180.801 -106.4z"/> + </g> + <g style="fill: #cc7226"> + <path d="M168.33 -108.509C169.137 -107.877 170.156 -107.779 170.761 -106.97C170.995 -106.656 170.706 -106.33 170.391 -106.233C169.348 -105.916 168.292 -106.486 167.15 -105.898C166.748 -105.691 166.106 -105.873 165.553 -106.022C163.921 -106.463 162.092 -106.488 160.401 -105.8C158.416 -106.929 156.056 -106.345 153.975 -107.346C153.917 -107.373 153.695 -107.027 153.621 -107.054C150.575 -108.199 146.832 -107.916 144.401 -110.2C141.973 -110.612 139.616 -111.074 137.188 -111.754C135.37 -112.263 133.961 -113.252 132.341 -114.084C130.964 -114.792 129.507 -115.314 127.973 -115.686C126.11 -116.138 124.279 -116.026 122.386 -116.546C122.293 -116.571 122.101 -116.227 122.019 -116.254C121.695 -116.362 121.405 -116.945 121.234 -116.892C119.553 -116.37 118.065 -117.342 116.401 -117C115.223 -118.224 113.495 -117.979 111.949 -118.421C108.985 -119.269 105.831 -117.999 102.801 -119C106.914 -120.842 111.601 -119.61 115.663 -121.679C117.991 -122.865 120.653 -121.763 123.223 -122.523C123.71 -122.667 124.401 -122.869 124.801 -122.2C124.935 -122.335 125.117 -122.574 125.175 -122.546C127.625 -121.389 129.94 -120.115 132.422 -119.049C132.763 -118.903 133.295 -119.135 133.547 -118.933C135.067 -117.717 137.01 -117.82 138.401 -116.6C140.099 -117.102 141.892 -116.722 143.621 -117.346C143.698 -117.373 143.932 -117.032 143.965 -117.054C145.095 -117.802 146.25 -117.531 147.142 -117.227C147.48 -117.112 148.143 -116.865 148.448 -116.791C149.574 -116.515 150.43 -116.035 151.609 -115.852C151.723 -115.834 151.908 -116.174 151.98 -116.146C153.103 -115.708 154.145 -115.764 154.801 -114.6C154.936 -114.735 155.101 -114.973 155.183 -114.946C156.21 -114.608 156.859 -113.853 157.96 -113.612C158.445 -113.506 159.057 -112.88 159.633 -112.704C162.025 -111.973 163.868 -110.444 166.062 -109.549C166.821 -109.239 167.697 -109.005 168.33 -108.509z"/> + </g> + <g style="fill: #cc7226"> + <path d="M91.696 -122.739C89.178 -124.464 86.81 -125.57 84.368 -127.356C84.187 -127.489 83.827 -127.319 83.625 -127.441C82.618 -128.05 81.73 -128.631 80.748 -129.327C80.209 -129.709 79.388 -129.698 78.88 -129.956C76.336 -131.248 73.707 -131.806 71.2 -133C71.882 -133.638 73.004 -133.394 73.6 -134.2C73.795 -133.92 74.033 -133.636 74.386 -133.827C76.064 -134.731 77.914 -134.884 79.59 -134.794C81.294 -134.702 83.014 -134.397 84.789 -134.125C85.096 -134.078 85.295 -133.555 85.618 -133.458C87.846 -132.795 90.235 -133.32 92.354 -132.482C93.945 -131.853 95.515 -131.03 96.754 -129.755C97.006 -129.495 96.681 -129.194 96.401 -129C96.789 -129.109 97.062 -128.903 97.173 -128.59C97.257 -128.351 97.257 -128.049 97.173 -127.81C97.061 -127.498 96.782 -127.397 96.408 -127.346C95.001 -127.156 96.773 -128.536 96.073 -128.088C94.8 -127.274 95.546 -125.868 94.801 -124.6C94.521 -124.794 94.291 -125.012 94.401 -125.4C94.635 -124.878 94.033 -124.588 93.865 -124.272C93.48 -123.547 92.581 -122.132 91.696 -122.739z"/> + </g> + <g style="fill: #cc7226"> + <path d="M59.198 -115.391C56.044 -116.185 52.994 -116.07 49.978 -117.346C49.911 -117.374 49.688 -117.027 49.624 -117.054C48.258 -117.648 47.34 -118.614 46.264 -119.66C45.351 -120.548 43.693 -120.161 42.419 -120.648C42.095 -120.772 41.892 -121.284 41.591 -121.323C40.372 -121.48 39.445 -122.429 38.4 -123C40.736 -123.795 43.147 -123.764 45.609 -124.148C45.722 -124.166 45.867 -123.845 46 -123.845C46.136 -123.845 46.266 -124.066 46.4 -124.2C46.595 -123.92 46.897 -123.594 47.154 -123.848C47.702 -124.388 48.258 -124.198 48.798 -124.158C48.942 -124.148 49.067 -123.845 49.2 -123.845C49.336 -123.845 49.467 -124.156 49.6 -124.156C49.736 -124.155 49.867 -123.845 50 -123.845C50.136 -123.845 50.266 -124.066 50.4 -124.2C51.092 -123.418 51.977 -123.972 52.799 -123.793C53.837 -123.566 54.104 -122.418 55.178 -122.12C59.893 -120.816 64.03 -118.671 68.393 -116.584C68.7 -116.437 68.91 -116.189 68.8 -115.8C69.067 -115.8 69.38 -115.888 69.57 -115.756C70.628 -115.024 71.669 -114.476 72.366 -113.378C72.582 -113.039 72.253 -112.632 72.02 -112.684C67.591 -113.679 63.585 -114.287 59.198 -115.391z"/> + </g> + <g style="fill: #cc7226"> + <path d="M45.338 -71.179C43.746 -72.398 43.162 -74.429 42.034 -76.221C41.82 -76.561 42.094 -76.875 42.411 -76.964C42.971 -77.123 43.514 -76.645 43.923 -76.443C45.668 -75.581 47.203 -74.339 49.2 -74.2C51.19 -71.966 55.45 -71.581 55.457 -68.2C55.458 -67.341 54.03 -68.259 53.6 -67.4C51.149 -68.403 48.76 -68.3 46.38 -69.767C45.763 -70.148 46.093 -70.601 45.338 -71.179z"/> + </g> + <g style="fill: #cc7226"> + <path d="M17.8 -123.756C17.935 -123.755 24.966 -123.522 24.949 -123.408C24.904 -123.099 17.174 -122.05 16.81 -122.22C16.646 -122.296 9.134 -119.866 9 -120C9.268 -120.135 17.534 -123.756 17.8 -123.756z"/> + </g> + <g style="fill: #000000"> + <path d="M33.2 -114C33.2 -114 18.4 -112.2 14 -111C9.6 -109.8 -9 -102.2 -12 -100.2C-12 -100.2 -25.4 -94.8 -42.4 -74.8C-42.4 -74.8 -34.8 -78.2 -32.6 -81C-32.6 -81 -19 -93.6 -19.2 -91C-19.2 -91 -7 -99.6 -7.6 -97.4C-7.6 -97.4 16.8 -108.6 14.8 -105.4C14.8 -105.4 36.4 -110 35.4 -108C35.4 -108 54.2 -103.6 51.4 -103.4C51.4 -103.4 45.6 -102.2 52 -98.6C52 -98.6 48.6 -94.2 43.2 -98.2C37.8 -102.2 40.8 -100 35.8 -99C35.8 -99 33.2 -98.2 28.6 -102.2C28.6 -102.2 23 -106.8 14.2 -103.2C14.2 -103.2 -16.4 -90.6 -18.4 -90C-18.4 -90 -22 -87.2 -24.4 -83.6C-24.4 -83.6 -30.2 -79.2 -33.2 -77.8C-33.2 -77.8 -46 -66.2 -47.2 -64.8C-47.2 -64.8 -50.6 -59.6 -51.4 -59.2C-51.4 -59.2 -45 -63 -43 -65C-43 -65 -29 -75 -23.6 -75.8C-23.6 -75.8 -19.2 -78.8 -18.4 -80.2C-18.4 -80.2 -4 -89.4 0.2 -89.4C0.2 -89.4 9.4 -84.2 11.8 -91.2C11.8 -91.2 17.6 -93 23.2 -91.8C23.2 -91.8 26.4 -94.4 25.6 -96.6C25.6 -96.6 27.2 -98.4 28.2 -94.6C28.2 -94.6 31.6 -91 36.4 -93C36.4 -93 40.4 -93.2 38.4 -90.8C38.4 -90.8 34 -87 22.2 -86.8C22.2 -86.8 9.8 -86.2 -6.6 -78.6C-6.6 -78.6 -36.4 -68.2 -45.6 -57.8C-45.6 -57.8 -52 -49 -57.4 -47.8C-57.4 -47.8 -63.2 -47 -69.2 -39.6C-69.2 -39.6 -59.4 -45.4 -50.4 -45.4C-50.4 -45.4 -46.4 -47.8 -50.2 -44.2C-50.2 -44.2 -53.8 -36.6 -52.2 -31.2C-52.2 -31.2 -52.8 -26 -53.6 -24.4C-53.6 -24.4 -61.4 -11.6 -61.4 -9.2C-61.4 -6.8 -60.2 3 -59.8 3.6C-59.4 4.2 -60.8 2 -57 4.4C-53.2 6.8 -50.4 8.4 -49.6 11.2C-48.8 14 -51.6 5.8 -51.8 4C-52 2.2 -56.2 -5 -55.4 -7.4C-55.4 -7.4 -54.4 -6.4 -53.6 -5C-53.6 -5 -54.2 -5.6 -53.6 -9.2C-53.6 -9.2 -52.8 -14.4 -51.4 -17.6C-50 -20.8 -48 -24.6 -47.6 -25.4C-47.2 -26.2 -47.2 -32 -45.8 -29.4L-42.4 -26.8C-42.4 -26.8 -45.2 -29.4 -43 -31.6C-43 -31.6 -44 -37.2 -42.2 -39.8C-42.2 -39.8 -35.2 -48.2 -33.6 -49.2C-32 -50.2 -33.4 -49.8 -33.4 -49.8C-33.4 -49.8 -27.4 -54 -33.2 -52.4C-33.2 -52.4 -37.2 -50.8 -40.2 -50.8C-40.2 -50.8 -47.8 -48.8 -43.8 -53C-39.8 -57.2 -29.8 -62.6 -26 -62.4L-25.2 -60.8L-14 -63.2L-15.2 -62.4C-15.2 -62.4 -15.4 -62.6 -11.2 -63C-7 -63.4 -1.2 -62 0.2 -63.8C1.6 -65.6 5 -66.6 4.6 -65.2C4.2 -63.8 4 -61.8 4 -61.8C4 -61.8 9 -67.6 8.4 -65.4C7.8 -63.2 -0.4 -58 -1.8 -51.8L8.6 -60L12.2 -63C12.2 -63 15.8 -60.8 16 -62.4C16.2 -64 20.8 -69.8 22 -69.6C23.2 -69.4 25.2 -72.2 25 -69.6C24.8 -67 32.4 -61.6 32.4 -61.6C32.4 -61.6 35.6 -63.4 37 -62C38.4 -60.6 42.6 -81.8 42.6 -81.8L67.6 -92.4L111.201 -95.8L94.201 -102.6L33.2 -114z"/> + </g> + <g style="stroke:#4c0000; stroke-width:2"> + <path d="M51.4 85C51.4 85 36.4 68.2 28 65.6C28 65.6 14.6 58.8 -10 66.6"/> + </g> + <g style="stroke:#4c0000; stroke-width:2"> + <path d="M24.8 64.2C24.8 64.2 -0.4 56.2 -15.8 60.4C-15.8 60.4 -34.2 62.4 -42.6 76.2"/> + </g> + <g style="stroke:#4c0000; stroke-width:2"> + <path d="M21.2 63C21.2 63 4.2 55.8 -10.6 53.6C-10.6 53.6 -27.2 51 -43.8 58.2C-43.8 58.2 -56 64.2 -61.4 74.4"/> + </g> + <g style="stroke:#4c0000; stroke-width:2"> + <path d="M22.2 63.4C22.2 63.4 6.8 52.4 5.8 51C5.8 51 -1.2 40 -14.2 39.6C-14.2 39.6 -35.6 40.4 -52.8 48.4"/> + </g> + <g style="fill: #000000"> + <path d="M20.895 54.407C22.437 55.87 49.4 84.8 49.4 84.8C84.6 121.401 56.6 87.2 56.6 87.2C49 82.4 39.8 63.6 39.8 63.6C38.6 60.8 53.8 70.8 53.8 70.8C57.8 71.6 71.4 90.8 71.4 90.8C64.6 88.4 69.4 95.6 69.4 95.6C72.2 97.6 92.601 113.201 92.601 113.201C96.201 117.201 100.201 118.801 100.201 118.801C114.201 113.601 107.801 126.801 107.801 126.801C110.201 133.601 115.801 122.001 115.801 122.001C127.001 105.2 110.601 107.601 110.601 107.601C80.6 110.401 73.8 94.4 73.8 94.4C71.4 92 80.2 94.4 80.2 94.4C88.601 96.4 73 82 73 82C75.4 82 84.6 88.8 84.6 88.8C95.001 98 97.001 96 97.001 96C115.001 87.2 125.401 94.8 125.401 94.8C127.401 96.4 121.801 103.2 123.401 108.401C125.001 113.601 129.801 126.001 129.801 126.001C127.401 127.601 127.801 138.401 127.801 138.401C144.601 161.601 135.001 159.601 135.001 159.601C119.401 159.201 134.201 166.801 134.201 166.801C137.401 168.801 146.201 176.001 146.201 176.001C143.401 174.801 141.801 180.001 141.801 180.001C146.601 184.001 143.801 188.801 143.801 188.801C137.801 190.001 136.601 194.001 136.601 194.001C143.401 202.001 133.401 202.401 133.401 202.401C137.001 206.801 132.201 218.801 132.201 218.801C127.401 218.801 121.001 224.401 121.001 224.401C123.401 229.201 113.001 234.801 113.001 234.801C104.601 236.401 107.401 243.201 107.401 243.201C99.401 249.201 97.001 265.201 97.001 265.201C96.201 275.601 93.801 278.801 99.001 276.801C104.201 274.801 103.401 262.401 103.401 262.401C98.601 246.801 141.401 230.801 141.401 230.801C145.401 229.201 146.201 224.001 146.201 224.001C148.201 224.401 157.001 232.001 157.001 232.001C164.601 243.201 165.001 234.001 165.001 234.001C166.201 230.401 164.601 224.401 164.601 224.401C170.601 202.801 156.601 196.401 156.601 196.401C146.601 162.801 160.601 171.201 160.601 171.201C163.401 176.801 174.201 182.001 174.201 182.001L177.801 179.601C176.201 174.801 184.601 168.801 184.601 168.801C187.401 175.201 193.401 167.201 193.401 167.201C197.001 142.801 209.401 157.201 209.401 157.201C213.401 158.401 214.601 151.601 214.601 151.601C218.201 141.201 214.601 127.601 214.601 127.601C218.201 127.201 227.801 133.201 227.801 133.201C230.601 129.601 221.401 112.801 225.401 115.201C229.401 117.601 233.801 119.201 233.801 119.201C234.601 117.201 224.601 104.801 224.601 104.801C220.201 102 215.001 81.6 215.001 81.6C222.201 85.2 212.201 70 212.201 70C212.201 66.8 218.201 55.6 218.201 55.6C217.401 48.8 218.201 49.2 218.201 49.2C221.001 50.4 229.001 52 222.201 45.6C215.401 39.2 223.001 34.4 223.001 34.4C227.401 31.6 213.801 32 213.801 32C208.601 27.6 209.001 23.6 209.001 23.6C217.001 25.6 202.601 11.2 200.201 7.6C197.801 4 207.401 -1.2 207.401 -1.2C220.601 -4.8 209.001 -8 209.001 -8C189.401 -7.6 200.201 -18.4 200.201 -18.4C206.201 -18 204.601 -20.4 204.601 -20.4C199.401 -21.6 189.801 -28 189.801 -28C185.801 -31.6 189.401 -30.8 189.401 -30.8C206.201 -29.6 177.401 -40.8 177.401 -40.8C185.401 -40.8 167.401 -51.2 167.401 -51.2C165.401 -52.8 162.201 -60.4 162.201 -60.4C156.201 -65.6 151.401 -72.4 151.401 -72.4C151.001 -76.8 146.201 -81.6 146.201 -81.6C134.601 -95.2 129.001 -94.8 129.001 -94.8C114.201 -98.4 109.001 -97.6 109.001 -97.6L56.2 -93.2C29.8 -80.4 37.6 -59.4 37.6 -59.4C44 -51 53.2 -54.8 53.2 -54.8C57.8 -61 69.4 -58.8 69.4 -58.8C89.801 -55.6 87.201 -59.2 87.201 -59.2C84.801 -63.8 68.6 -70 68.4 -70.6C68.2 -71.2 59.4 -74.6 59.4 -74.6C56.4 -75.8 52 -85 52 -85C48.8 -88.4 64.6 -82.6 64.6 -82.6C63.4 -81.6 70.8 -77.6 70.8 -77.6C88.201 -78.6 98.801 -67.8 98.801 -67.8C109.601 -51.2 109.801 -59.4 109.801 -59.4C112.601 -68.8 100.801 -90 100.801 -90C101.201 -92 109.401 -85.4 109.401 -85.4C110.801 -87.4 111.601 -81.6 111.601 -81.6C111.801 -79.2 115.601 -71.2 115.601 -71.2C118.401 -58.2 122.001 -65.6 122.001 -65.6L126.601 -56.2C128.001 -53.6 122.001 -46 122.001 -46C121.801 -43.2 122.601 -43.4 117.001 -35.8C111.401 -28.2 114.801 -23.8 114.801 -23.8C113.401 -17.2 122.201 -17.6 122.201 -17.6C124.801 -15.4 128.201 -15.4 128.201 -15.4C130.001 -13.4 132.401 -14 132.401 -14C134.001 -17.8 140.201 -15.8 140.201 -15.8C141.601 -18.2 149.801 -18.6 149.801 -18.6C150.801 -21.2 151.201 -22.8 154.601 -23.4C158.001 -24 133.401 -67 133.401 -67C139.801 -67.8 131.601 -80.2 131.601 -80.2C129.401 -86.8 140.801 -72.2 143.001 -70.8C145.201 -69.4 146.201 -67.2 144.601 -67.4C143.001 -67.6 141.201 -65.4 142.601 -65.2C144.001 -65 157.001 -50 160.401 -39.8C163.801 -29.6 169.801 -25.6 176.001 -19.6C182.201 -13.6 181.401 10.6 181.401 10.6C181.001 19.4 187.001 30 187.001 30C189.001 33.8 184.801 52 184.801 52C182.801 54.2 184.201 55 184.201 55C185.201 56.2 192.001 69.4 192.001 69.4C190.201 69.2 193.801 72.8 193.801 72.8C199.001 78.8 192.601 75.8 192.601 75.8C186.601 74.2 193.601 84 193.601 84C194.801 85.8 185.801 81.2 185.801 81.2C176.601 80.6 188.201 87.8 188.201 87.8C196.801 95 185.401 90.6 185.401 90.6C180.801 88.8 184.001 95.6 184.001 95.6C187.201 97.2 204.401 104.2 204.401 104.2C204.801 108.001 201.801 113.001 201.801 113.001C202.201 117.001 200.001 120.401 200.001 120.401C198.801 128.601 198.201 129.401 198.201 129.401C194.001 129.601 186.601 143.401 186.601 143.401C184.801 146.001 174.601 158.001 174.601 158.001C172.601 165.001 154.601 157.801 154.601 157.801C148.001 161.201 150.001 157.801 150.001 157.801C149.601 155.601 154.401 149.601 154.401 149.601C161.401 147.001 158.801 136.201 158.801 136.201C162.801 134.801 151.601 132.001 151.801 130.801C152.001 129.601 157.801 128.201 157.801 128.201C165.801 126.201 161.401 123.801 161.401 123.801C160.801 119.801 163.801 114.201 163.801 114.201C175.401 113.401 163.801 97.2 163.801 97.2C153.001 89.6 152.001 83.8 152.001 83.8C164.601 75.6 156.401 63.2 156.601 59.6C156.801 56 158.001 34.4 158.001 34.4C156.001 28.2 153.001 14.6 153.001 14.6C155.201 9.4 162.601 -3.2 162.601 -3.2C165.401 -7.4 174.201 -12.2 172.001 -15.2C169.801 -18.2 162.001 -16.4 162.001 -16.4C154.201 -17.8 154.801 -12.6 154.801 -12.6C153.201 -11.6 152.401 -6.6 152.401 -6.6C151.68 1.333 142.801 7.6 142.801 7.6C131.601 13.8 140.801 17.8 140.801 17.8C146.801 24.4 137.001 24.6 137.001 24.6C126.001 22.8 134.201 33 134.201 33C145.001 45.8 142.001 48.6 142.001 48.6C131.801 49.6 144.401 58.8 144.401 58.8C144.401 58.8 143.601 56.8 143.801 58.6C144.001 60.4 147.001 64.6 147.801 66.6C148.601 68.6 144.601 68.8 144.601 68.8C145.201 78.4 129.801 74.2 129.801 74.2C129.801 74.2 129.801 74.2 128.201 74.4C126.601 74.6 115.401 73.8 109.601 71.6C103.801 69.4 97.001 69.4 97.001 69.4C97.001 69.4 93.001 71.2 85.4 71C77.8 70.8 69.8 73.6 69.8 73.6C65.4 73.2 74 68.8 74.2 69C74.4 69.2 80 63.6 72 64.2C50.203 65.835 39.4 55.6 39.4 55.6C37.4 54.2 34.8 51.4 34.8 51.4C24.8 49.4 36.2 63.8 36.2 63.8C37.4 65.2 36 66.2 36 66.2C35.2 64.6 27.4 59.2 27.4 59.2C24.589 58.227 23.226 56.893 20.895 54.407z"/> + </g> + <g style="fill: #4c0000"> + <path d="M-3 42.8C-3 42.8 8.6 48.4 11.2 51.2C13.8 54 27.8 65.4 27.8 65.4C27.8 65.4 22.4 63.4 19.8 61.6C17.2 59.8 6.4 51.6 6.4 51.6C6.4 51.6 2.6 45.6 -3 42.8z"/> + </g> + <g style="fill: #99cc32"> + <path d="M-61.009 11.603C-60.672 11.455 -61.196 8.743 -61.4 8.2C-62.422 5.474 -71.4 4 -71.4 4C-71.627 5.365 -71.682 6.961 -71.576 8.599C-71.576 8.599 -66.708 14.118 -61.009 11.603z"/> + </g> + <g style="fill: #659900"> + <path d="M-61.009 11.403C-61.458 11.561 -61.024 8.669 -61.2 8.2C-62.222 5.474 -71.4 3.9 -71.4 3.9C-71.627 5.265 -71.682 6.861 -71.576 8.499C-71.576 8.499 -67.308 13.618 -61.009 11.403z"/> + </g> + <g style="fill: #000000"> + <path d="M-65.4 11.546C-66.025 11.546 -66.531 10.406 -66.531 9C-66.531 7.595 -66.025 6.455 -65.4 6.455C-64.775 6.455 -64.268 7.595 -64.268 9C-64.268 10.406 -64.775 11.546 -65.4 11.546z"/> + </g> + <g style="fill: #000000"> + <path d="M-65.4 9z"/> + </g> + <g style="fill: #000000"> + <path d="M-111 109.601C-111 109.601 -116.6 119.601 -91.8 113.601C-91.8 113.601 -77.8 112.401 -75.4 110.001C-74.2 110.801 -65.834 113.734 -63 114.401C-56.2 116.001 -47.8 106 -47.8 106C-47.8 106 -43.2 95.5 -40.4 95.5C-37.6 95.5 -40.8 97.1 -40.8 97.1C-40.8 97.1 -47.4 107.201 -47 108.801C-47 108.801 -52.2 128.801 -68.2 129.601C-68.2 129.601 -84.35 130.551 -83 136.401C-83 136.401 -74.2 134.001 -71.8 136.401C-71.8 136.401 -61 136.001 -69 142.401L-75.8 154.001C-75.8 154.001 -75.66 157.919 -85.8 154.401C-95.6 151.001 -105.9 138.101 -105.9 138.101C-105.9 138.101 -121.85 123.551 -111 109.601z"/> + </g> + <g style="fill: #e59999"> + <path d="M-112.2 113.601C-112.2 113.601 -114.2 123.201 -77.4 112.801C-77.4 112.801 -73 112.801 -70.6 113.601C-68.2 114.401 -56.2 117.201 -54.2 116.001C-54.2 116.001 -61.4 129.601 -73 128.001C-73 128.001 -86.2 129.601 -85.8 134.401C-85.8 134.401 -81.8 141.601 -77 144.001C-77 144.001 -74.2 146.401 -74.6 149.601C-75 152.801 -77.8 154.401 -79.8 155.201C-81.8 156.001 -85 152.801 -86.6 152.801C-88.2 152.801 -96.6 146.401 -101 141.601C-105.4 136.801 -113.8 124.801 -113.4 122.001C-113 119.201 -112.2 113.601 -112.2 113.601z"/> + </g> + <g style="fill: #b26565"> + <path d="M-109 131.051C-106.4 135.001 -103.2 139.201 -101 141.601C-96.6 146.401 -88.2 152.801 -86.6 152.801C-85 152.801 -81.8 156.001 -79.8 155.201C-77.8 154.401 -75 152.801 -74.6 149.601C-74.2 146.401 -77 144.001 -77 144.001C-80.066 142.468 -82.806 138.976 -84.385 136.653C-84.385 136.653 -84.2 139.201 -89.4 138.401C-94.6 137.601 -99.8 134.801 -101.4 131.601C-103 128.401 -105.4 126.001 -103.8 129.601C-102.2 133.201 -99.8 136.801 -98.2 137.201C-96.6 137.601 -97 138.801 -99.4 138.401C-101.8 138.001 -104.6 137.601 -109 132.401z"/> + </g> + <g style="fill: #992600"> + <path d="M-111.6 110.001C-111.6 110.001 -109.8 96.4 -108.6 92.4C-108.6 92.4 -109.4 85.6 -107 81.4C-104.6 77.2 -102.6 71 -99.6 65.6C-96.6 60.2 -96.4 56.2 -92.4 54.6C-88.4 53 -82.4 44.4 -79.6 43.4C-76.8 42.4 -77 43.2 -77 43.2C-77 43.2 -70.2 28.4 -56.6 32.4C-56.6 32.4 -72.8 29.6 -57 20.2C-57 20.2 -61.8 21.3 -58.5 14.3C-56.299 9.632 -56.8 16.4 -67.8 28.2C-67.8 28.2 -72.8 36.8 -78 39.8C-83.2 42.8 -95.2 49.8 -96.4 53.6C-97.6 57.4 -100.8 63.2 -102.8 64.8C-104.8 66.4 -107.6 70.6 -108 74C-108 74 -109.2 78 -110.6 79.2C-112 80.4 -112.2 83.6 -112.2 85.6C-112.2 87.6 -114.2 90.4 -114 92.8C-114 92.8 -113.2 111.801 -113.6 113.801L-111.6 110.001z"/> + </g> + <g style="fill: #ffffff"> + <path d="M-120.2 114.601C-120.2 114.601 -122.2 113.201 -126.6 119.201C-126.6 119.201 -119.3 152.201 -119.3 153.601C-119.3 153.601 -118.2 151.501 -119.5 144.301C-120.8 137.101 -121.7 124.401 -121.7 124.401L-120.2 114.601z"/> + </g> + <g style="fill: #992600"> + <path d="M-98.6 54C-98.6 54 -116.2 57.2 -115.8 86.4L-116.6 111.201C-116.6 111.201 -117.8 85.6 -119 84C-120.2 82.4 -116.2 71.2 -119.4 77.2C-119.4 77.2 -133.4 91.2 -125.4 112.401C-125.4 112.401 -123.9 115.701 -126.9 111.101C-126.9 111.101 -131.5 98.5 -130.4 92.1C-130.4 92.1 -130.2 89.9 -128.3 87.1C-128.3 87.1 -119.7 75.4 -117 73.1C-117 73.1 -115.2 58.7 -99.8 53.5C-99.8 53.5 -94.1 51.2 -98.6 54z"/> + </g> + <g style="fill: #000000"> + <path d="M40.8 -12.2C41.46 -12.554 41.451 -13.524 42.031 -13.697C43.18 -14.041 43.344 -15.108 43.862 -15.892C44.735 -17.211 44.928 -18.744 45.51 -20.235C45.782 -20.935 45.809 -21.89 45.496 -22.55C44.322 -25.031 43.62 -27.48 42.178 -29.906C41.91 -30.356 41.648 -31.15 41.447 -31.748C40.984 -33.132 39.727 -34.123 38.867 -35.443C38.579 -35.884 39.104 -36.809 38.388 -36.893C37.491 -36.998 36.042 -37.578 35.809 -36.552C35.221 -33.965 36.232 -31.442 37.2 -29C36.418 -28.308 36.752 -27.387 36.904 -26.62C37.614 -23.014 36.416 -19.662 35.655 -16.188C35.632 -16.084 35.974 -15.886 35.946 -15.824C34.724 -13.138 33.272 -10.693 31.453 -8.312C30.695 -7.32 29.823 -6.404 29.326 -5.341C28.958 -4.554 28.55 -3.588 28.8 -2.6C25.365 0.18 23.115 4.025 20.504 7.871C20.042 8.551 20.333 9.76 20.884 10.029C21.697 10.427 22.653 9.403 23.123 8.557C23.512 7.859 23.865 7.209 24.356 6.566C24.489 6.391 24.31 5.972 24.445 5.851C27.078 3.504 28.747 0.568 31.2 -1.8C33.15 -2.129 34.687 -3.127 36.435 -4.14C36.743 -4.319 37.267 -4.07 37.557 -4.265C39.31 -5.442 39.308 -7.478 39.414 -9.388C39.464 -10.272 39.66 -11.589 40.8 -12.2z"/> + </g> + <g style="fill: #000000"> + <path d="M31.959 -16.666C32.083 -16.743 31.928 -17.166 32.037 -17.382C32.199 -17.706 32.602 -17.894 32.764 -18.218C32.873 -18.434 32.71 -18.814 32.846 -18.956C35.179 -21.403 35.436 -24.427 34.4 -27.4C35.424 -28.02 35.485 -29.282 35.06 -30.129C34.207 -31.829 34.014 -33.755 33.039 -35.298C32.237 -36.567 30.659 -37.811 29.288 -36.508C28.867 -36.108 28.546 -35.321 28.824 -34.609C28.888 -34.446 29.173 -34.3 29.146 -34.218C29.039 -33.894 28.493 -33.67 28.487 -33.398C28.457 -31.902 27.503 -30.391 28.133 -29.062C28.905 -27.433 29.724 -25.576 30.4 -23.8C29.166 -21.684 30.199 -19.235 28.446 -17.358C28.31 -17.212 28.319 -16.826 28.441 -16.624C28.733 -16.138 29.139 -15.732 29.625 -15.44C29.827 -15.319 30.175 -15.317 30.375 -15.441C30.953 -15.803 31.351 -16.29 31.959 -16.666z"/> + </g> + <g style="fill: #000000"> + <path d="M94.771 -26.977C96.16 -25.185 96.45 -22.39 94.401 -21C94.951 -17.691 98.302 -19.67 100.401 -20.2C100.292 -20.588 100.519 -20.932 100.802 -20.937C101.859 -20.952 102.539 -21.984 103.601 -21.8C104.035 -23.357 105.673 -24.059 106.317 -25.439C108.043 -29.134 107.452 -33.407 104.868 -36.653C104.666 -36.907 104.883 -37.424 104.759 -37.786C104.003 -39.997 101.935 -40.312 100.001 -41C98.824 -44.875 98.163 -48.906 96.401 -52.6C94.787 -52.85 94.089 -54.589 92.752 -55.309C91.419 -56.028 90.851 -54.449 90.892 -53.403C90.899 -53.198 91.351 -52.974 91.181 -52.609C91.105 -52.445 90.845 -52.334 90.845 -52.2C90.846 -52.065 91.067 -51.934 91.201 -51.8C90.283 -50.98 88.86 -50.503 88.565 -49.358C87.611 -45.648 90.184 -42.523 91.852 -39.322C92.443 -38.187 91.707 -36.916 90.947 -35.708C90.509 -35.013 90.617 -33.886 90.893 -33.03C91.645 -30.699 93.236 -28.96 94.771 -26.977z"/> + </g> + <g style="fill: #000000"> + <path d="M57.611 -8.591C56.124 -6.74 52.712 -4.171 55.629 -2.243C55.823 -2.114 56.193 -2.11 56.366 -2.244C58.387 -3.809 60.39 -4.712 62.826 -5.294C62.95 -5.323 63.224 -4.856 63.593 -5.017C65.206 -5.72 67.216 -5.662 68.4 -7C72.167 -6.776 75.732 -7.892 79.123 -9.2C80.284 -9.648 81.554 -10.207 82.755 -10.709C84.131 -11.285 85.335 -12.213 86.447 -13.354C86.58 -13.49 86.934 -13.4 87.201 -13.4C87.161 -14.263 88.123 -14.39 88.37 -15.012C88.462 -15.244 88.312 -15.64 88.445 -15.742C90.583 -17.372 91.503 -19.39 90.334 -21.767C90.049 -22.345 89.8 -22.963 89.234 -23.439C88.149 -24.35 87.047 -23.496 86 -23.8C85.841 -23.172 85.112 -23.344 84.726 -23.146C83.867 -22.707 82.534 -23.292 81.675 -22.854C80.313 -22.159 79.072 -21.99 77.65 -21.613C77.338 -21.531 76.56 -21.627 76.4 -21C76.266 -21.134 76.118 -21.368 76.012 -21.346C74.104 -20.95 72.844 -20.736 71.543 -19.044C71.44 -18.911 70.998 -19.09 70.839 -18.955C69.882 -18.147 69.477 -16.913 68.376 -16.241C68.175 -16.118 67.823 -16.286 67.629 -16.157C66.983 -15.726 66.616 -15.085 65.974 -14.638C65.645 -14.409 65.245 -14.734 65.277 -14.99C65.522 -16.937 66.175 -18.724 65.6 -20.6C67.677 -23.12 70.194 -25.069 72 -27.8C72.015 -29.966 72.707 -32.112 72.594 -34.189C72.584 -34.382 72.296 -35.115 72.17 -35.462C71.858 -36.316 72.764 -37.382 71.92 -38.106C70.516 -39.309 69.224 -38.433 68.4 -37C66.562 -36.61 64.496 -35.917 62.918 -37.151C61.911 -37.938 61.333 -38.844 60.534 -39.9C59.549 -41.202 59.884 -42.638 59.954 -44.202C59.96 -44.33 59.645 -44.466 59.645 -44.6C59.646 -44.735 59.866 -44.866 60 -45C59.294 -45.626 59.019 -46.684 58 -47C58.305 -48.092 57.629 -48.976 56.758 -49.278C54.763 -49.969 53.086 -48.057 51.194 -47.984C50.68 -47.965 50.213 -49.003 49.564 -49.328C49.132 -49.544 48.428 -49.577 48.066 -49.311C47.378 -48.807 46.789 -48.693 46.031 -48.488C44.414 -48.052 43.136 -46.958 41.656 -46.103C40.171 -45.246 39.216 -43.809 38.136 -42.489C37.195 -41.337 37.059 -38.923 38.479 -38.423C40.322 -37.773 41.626 -40.476 43.592 -40.15C43.904 -40.099 44.11 -39.788 44 -39.4C44.389 -39.291 44.607 -39.52 44.8 -39.8C45.658 -38.781 46.822 -38.444 47.76 -37.571C48.73 -36.667 50.476 -37.085 51.491 -36.088C53.02 -34.586 52.461 -31.905 54.4 -30.6C53.814 -29.287 53.207 -28.01 52.872 -26.583C52.59 -25.377 53.584 -24.18 54.795 -24.271C56.053 -24.365 56.315 -25.124 56.8 -26.2C57.067 -25.933 57.536 -25.636 57.495 -25.42C57.038 -23.033 56.011 -21.04 55.553 -18.609C55.494 -18.292 55.189 -18.09 54.8 -18.2C54.332 -14.051 50.28 -11.657 47.735 -8.492C47.332 -7.99 47.328 -6.741 47.737 -6.338C49.14 -4.951 51.1 -6.497 52.8 -7C53.013 -8.206 53.872 -9.148 55.204 -9.092C55.46 -9.082 55.695 -9.624 56.019 -9.754C56.367 -9.892 56.869 -9.668 57.155 -9.866C58.884 -11.061 60.292 -12.167 62.03 -13.356C62.222 -13.487 62.566 -13.328 62.782 -13.436C63.107 -13.598 63.294 -13.985 63.617 -14.17C63.965 -14.37 64.207 -14.08 64.4 -13.8C63.754 -13.451 63.75 -12.494 63.168 -12.292C62.393 -12.024 61.832 -11.511 61.158 -11.064C60.866 -10.871 60.207 -11.119 60.103 -10.94C59.505 -9.912 58.321 -9.474 57.611 -8.591z"/> + </g> + <g style="fill: #000000"> + <path d="M2.2 -58C2.2 -58 -7.038 -60.872 -18.2 -35.2C-18.2 -35.2 -20.6 -30 -23 -28C-25.4 -26 -36.6 -22.4 -38.6 -18.4L-49 -2.4C-49 -2.4 -34.2 -18.4 -31 -20.8C-31 -20.8 -23 -29.2 -26.2 -22.4C-26.2 -22.4 -40.2 -11.6 -39 -2.4C-39 -2.4 -44.6 12 -45.4 14C-45.4 14 -29.4 -18 -27 -19.2C-24.6 -20.4 -23.4 -20.4 -24.6 -16.8C-25.8 -13.2 -26.2 3.2 -29 5.2C-29 5.2 -21 -15.2 -21.8 -18.4C-21.8 -18.4 -18.6 -22 -16.2 -16.8L-17.4 -0.8L-13 11.2C-13 11.2 -15.4 0 -13.8 -15.6C-13.8 -15.6 -15.8 -26 -11.8 -20.4C-7.8 -14.8 1.8 -8.8 1.8 -4C1.8 -4 -3.4 -21.6 -12.6 -26.4L-16.6 -20.4L-17.8 -22.4C-17.8 -22.4 -21.4 -23.2 -17 -30C-12.6 -36.8 -13 -37.6 -13 -37.6C-13 -37.6 -6.6 -30.4 -5 -30.4C-5 -30.4 8.2 -38 9.4 -13.6C9.4 -13.6 16.2 -28 7 -34.8C7 -34.8 -7.8 -36.8 -6.6 -42L0.6 -54.4C4.2 -59.6 2.6 -56.8 2.6 -56.8z"/> + </g> + <g style="fill: #000000"> + <path d="M-17.8 -41.6C-17.8 -41.6 -30.6 -41.6 -33.8 -36.4L-41 -26.8C-41 -26.8 -23.8 -36.8 -19.8 -38C-15.8 -39.2 -17.8 -41.6 -17.8 -41.6z"/> + </g> + <g style="fill: #000000"> + <path d="M-57.8 -35.2C-57.8 -35.2 -59.8 -34 -60.2 -31.2C-60.6 -28.4 -63 -28 -62.2 -25.2C-61.4 -22.4 -59.4 -20 -59.4 -24C-59.4 -28 -57.8 -30 -57 -31.2C-56.2 -32.4 -54.6 -36.8 -57.8 -35.2z"/> + </g> + <g style="fill: #000000"> + <path d="M-66.6 26C-66.6 26 -75 22 -78.2 18.4C-81.4 14.8 -80.948 19.966 -85.8 19.6C-91.647 19.159 -90.6 3.2 -90.6 3.2L-94.6 10.8C-94.6 10.8 -95.8 25.2 -87.8 22.8C-83.893 21.628 -82.6 23.2 -84.2 24C-85.8 24.8 -78.6 25.2 -81.4 26.8C-84.2 28.4 -69.8 23.2 -72.2 33.6L-66.6 26z"/> + </g> + <g style="fill: #000000"> + <path d="M-79.2 40.4C-79.2 40.4 -94.6 44.8 -98.2 35.2C-98.2 35.2 -103 37.6 -100.8 40.6C-98.6 43.6 -97.4 44 -97.4 44C-97.4 44 -92 45.2 -92.6 46C-93.2 46.8 -95.6 50.2 -95.6 50.2C-95.6 50.2 -85.4 44.2 -79.2 40.4z"/> + </g> + <g style="fill: #ffffff"> + <path d="M149.201 118.601C148.774 120.735 147.103 121.536 145.201 122.201C143.284 121.243 140.686 118.137 138.801 120.201C138.327 119.721 137.548 119.661 137.204 118.999C136.739 118.101 137.011 117.055 136.669 116.257C136.124 114.985 135.415 113.619 135.601 112.201C137.407 111.489 138.002 109.583 137.528 107.82C137.459 107.563 137.03 107.366 137.23 107.017C137.416 106.694 137.734 106.467 138.001 106.2C137.866 106.335 137.721 106.568 137.61 106.548C137 106.442 137.124 105.805 137.254 105.418C137.839 103.672 139.853 103.408 141.201 104.6C141.457 104.035 141.966 104.229 142.401 104.2C142.351 103.621 142.759 103.094 142.957 102.674C143.475 101.576 145.104 102.682 145.901 102.07C146.977 101.245 148.04 100.546 149.118 101.149C150.927 102.162 152.636 103.374 153.835 105.115C154.41 105.949 154.65 107.23 154.592 108.188C154.554 108.835 153.173 108.483 152.83 109.412C152.185 111.16 154.016 111.679 154.772 113.017C154.97 113.366 154.706 113.67 154.391 113.768C153.98 113.896 153.196 113.707 153.334 114.16C154.306 117.353 151.55 118.031 149.201 118.601z"/> + </g> + <g style="fill: #ffffff"> + <path d="M139.6 138.201C139.593 136.463 137.992 134.707 139.201 133.001C139.336 133.135 139.467 133.356 139.601 133.356C139.736 133.356 139.867 133.135 140.001 133.001C141.496 135.217 145.148 136.145 145.006 138.991C144.984 139.438 143.897 140.356 144.801 141.001C142.988 142.349 142.933 144.719 142.001 146.601C140.763 146.315 139.551 145.952 138.401 145.401C138.753 143.915 138.636 142.231 139.456 140.911C139.89 140.213 139.603 139.134 139.6 138.201z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-26.6 129.201C-26.6 129.201 -43.458 139.337 -29.4 124.001C-20.6 114.401 -10.6 108.801 -10.6 108.801C-10.6 108.801 -0.2 104.4 3.4 103.2C7 102 22.2 96.8 25.4 96.4C28.6 96 38.2 92 45 96C51.8 100 59.8 104.4 59.8 104.4C59.8 104.4 43.4 96 39.8 98.4C36.2 100.8 29 100.4 23 103.6C23 103.6 8.2 108.001 5 110.001C1.8 112.001 -8.6 123.601 -10.2 122.801C-11.8 122.001 -9.8 121.601 -8.6 118.801C-7.4 116.001 -9.4 114.401 -17.4 120.801C-25.4 127.201 -26.6 129.201 -26.6 129.201z"/> + </g> + <g style="fill: #000000"> + <path d="M-19.195 123.234C-19.195 123.234 -17.785 110.194 -9.307 111.859C-9.307 111.859 -1.081 107.689 1.641 105.721C1.641 105.721 9.78 104.019 11.09 103.402C29.569 94.702 44.288 99.221 44.835 98.101C45.381 96.982 65.006 104.099 68.615 108.185C69.006 108.628 58.384 102.588 48.686 100.697C40.413 99.083 18.811 100.944 7.905 106.48C4.932 107.989 -4.013 113.773 -6.544 113.662C-9.075 113.55 -19.195 123.234 -19.195 123.234z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-23 148.801C-23 148.801 -38.2 146.401 -21.4 144.801C-21.4 144.801 -3.4 142.801 0.6 137.601C0.6 137.601 14.2 128.401 17 128.001C19.8 127.601 49.8 120.401 50.2 118.001C50.6 115.601 56.2 115.601 57.8 116.401C59.4 117.201 58.6 118.401 55.8 119.201C53 120.001 21.8 136.401 15.4 137.601C9 138.801 -2.6 146.401 -7.4 147.601C-12.2 148.801 -23 148.801 -23 148.801z"/> + </g> + <g style="fill: #000000"> + <path d="M-3.48 141.403C-3.48 141.403 -12.062 140.574 -3.461 139.755C-3.461 139.755 5.355 136.331 7.403 133.668C7.403 133.668 14.367 128.957 15.8 128.753C17.234 128.548 31.194 124.861 31.399 123.633C31.604 122.404 65.67 109.823 70.09 113.013C73.001 115.114 63.1 113.437 53.466 117.847C52.111 118.467 18.258 133.054 14.981 133.668C11.704 134.283 5.765 138.174 3.307 138.788C0.85 139.403 -3.48 141.403 -3.48 141.403z"/> + </g> + <g style="fill: #000000"> + <path d="M-11.4 143.601C-11.4 143.601 -6.2 143.201 -7.4 144.801C-8.6 146.401 -11 145.601 -11 145.601L-11.4 143.601z"/> + </g> + <g style="fill: #000000"> + <path d="M-18.6 145.201C-18.6 145.201 -13.4 144.801 -14.6 146.401C-15.8 148.001 -18.2 147.201 -18.2 147.201L-18.6 145.201z"/> + </g> + <g style="fill: #000000"> + <path d="M-29 146.801C-29 146.801 -23.8 146.401 -25 148.001C-26.2 149.601 -28.6 148.801 -28.6 148.801L-29 146.801z"/> + </g> + <g style="fill: #000000"> + <path d="M-36.6 147.601C-36.6 147.601 -31.4 147.201 -32.6 148.801C-33.8 150.401 -36.2 149.601 -36.2 149.601L-36.6 147.601z"/> + </g> + <g style="fill: #000000"> + <path d="M1.8 108.001C1.8 108.001 6.2 108.001 5 109.601C3.8 111.201 0.6 110.801 0.6 110.801L1.8 108.001z"/> + </g> + <g style="fill: #000000"> + <path d="M-8.2 113.601C-8.2 113.601 -1.694 111.46 -4.2 114.801C-5.4 116.401 -7.8 115.601 -7.8 115.601L-8.2 113.601z"/> + </g> + <g style="fill: #000000"> + <path d="M-19.4 118.401C-19.4 118.401 -14.2 118.001 -15.4 119.601C-16.6 121.201 -19 120.401 -19 120.401L-19.4 118.401z"/> + </g> + <g style="fill: #000000"> + <path d="M-27 124.401C-27 124.401 -21.8 124.001 -23 125.601C-24.2 127.201 -26.6 126.401 -26.6 126.401L-27 124.401z"/> + </g> + <g style="fill: #000000"> + <path d="M-33.8 129.201C-33.8 129.201 -28.6 128.801 -29.8 130.401C-31 132.001 -33.4 131.201 -33.4 131.201L-33.8 129.201z"/> + </g> + <g style="fill: #000000"> + <path d="M5.282 135.598C5.282 135.598 12.203 135.066 10.606 137.195C9.009 139.325 5.814 138.26 5.814 138.26L5.282 135.598z"/> + </g> + <g style="fill: #000000"> + <path d="M15.682 130.798C15.682 130.798 22.603 130.266 21.006 132.395C19.409 134.525 16.214 133.46 16.214 133.46L15.682 130.798z"/> + </g> + <g style="fill: #000000"> + <path d="M26.482 126.398C26.482 126.398 33.403 125.866 31.806 127.995C30.209 130.125 27.014 129.06 27.014 129.06L26.482 126.398z"/> + </g> + <g style="fill: #000000"> + <path d="M36.882 121.598C36.882 121.598 43.803 121.066 42.206 123.195C40.609 125.325 37.414 124.26 37.414 124.26L36.882 121.598z"/> + </g> + <g style="fill: #000000"> + <path d="M9.282 103.598C9.282 103.598 16.203 103.066 14.606 105.195C13.009 107.325 9.014 107.06 9.014 107.06L9.282 103.598z"/> + </g> + <g style="fill: #000000"> + <path d="M19.282 100.398C19.282 100.398 26.203 99.866 24.606 101.995C23.009 104.125 18.614 103.86 18.614 103.86L19.282 100.398z"/> + </g> + <g style="fill: #000000"> + <path d="M-3.4 140.401C-3.4 140.401 1.8 140.001 0.6 141.601C-0.6 143.201 -3 142.401 -3 142.401L-3.4 140.401z"/> + </g> + <g style="fill: #992600"> + <path d="M-76.6 41.2C-76.6 41.2 -81 50 -81.4 53.2C-81.4 53.2 -80.6 44.4 -79.4 42.4C-78.2 40.4 -76.6 41.2 -76.6 41.2z"/> + </g> + <g style="fill: #992600"> + <path d="M-95 55.2C-95 55.2 -98.2 69.6 -97.8 72.4C-97.8 72.4 -99 60.8 -98.6 59.6C-98.2 58.4 -95 55.2 -95 55.2z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-74.2 -19.4L-74.4 -16.2L-76.6 -16C-76.6 -16 -62.4 -3.4 -61.8 4.2C-61.8 4.2 -61 -4 -74.2 -19.4z"/> + </g> + <g style="fill: #000000"> + <path d="M-70.216 -18.135C-70.647 -18.551 -70.428 -19.296 -70.836 -19.556C-71.645 -20.072 -69.538 -20.129 -69.766 -20.845C-70.149 -22.051 -69.962 -22.072 -70.084 -23.348C-70.141 -23.946 -69.553 -25.486 -69.168 -25.926C-67.722 -27.578 -69.046 -30.51 -67.406 -32.061C-67.102 -32.35 -66.726 -32.902 -66.441 -33.32C-65.782 -34.283 -64.598 -34.771 -63.648 -35.599C-63.33 -35.875 -63.531 -36.702 -62.962 -36.61C-62.248 -36.495 -61.007 -36.625 -61.052 -35.784C-61.165 -33.664 -62.494 -31.944 -63.774 -30.276C-63.323 -29.572 -63.781 -28.937 -64.065 -28.38C-65.4 -25.76 -65.211 -22.919 -65.385 -20.079C-65.39 -19.994 -65.697 -19.916 -65.689 -19.863C-65.336 -17.528 -64.752 -15.329 -63.873 -13.1C-63.507 -12.17 -63.036 -11.275 -62.886 -10.348C-62.775 -9.662 -62.672 -8.829 -63.08 -8.124C-61.045 -5.234 -62.354 -2.583 -61.185 0.948C-60.978 1.573 -59.286 3.487 -59.749 3.326C-62.262 2.455 -62.374 2.057 -62.551 1.304C-62.697 0.681 -63.027 -0.696 -63.264 -1.298C-63.328 -1.462 -63.499 -3.346 -63.577 -3.468C-65.09 -5.85 -63.732 -5.674 -65.102 -8.032C-66.53 -8.712 -67.496 -9.816 -68.619 -10.978C-68.817 -11.182 -67.674 -11.906 -67.855 -12.119C-68.947 -13.408 -70.1 -14.175 -69.764 -15.668C-69.609 -16.358 -69.472 -17.415 -70.216 -18.135z"/> + </g> + <g style="fill: #000000"> + <path d="M-73.8 -16.4C-73.8 -16.4 -73.4 -9.6 -71 -8C-68.6 -6.4 -69.8 -7.2 -73 -8.4C-76.2 -9.6 -75 -10.4 -75 -10.4C-75 -10.4 -77.8 -10 -75.4 -8C-73 -6 -69.4 -3.6 -71 -3.6C-72.6 -3.6 -80.2 -7.6 -80.2 -10.4C-80.2 -13.2 -81.2 -17.3 -81.2 -17.3C-81.2 -17.3 -80.1 -18.1 -75.3 -18C-75.3 -18 -73.9 -17.3 -73.8 -16.4z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-74.6 2.2C-74.6 2.2 -83.12 -0.591 -101.6 2.8C-101.6 2.8 -92.569 0.722 -73.8 3C-63.5 4.25 -74.6 2.2 -74.6 2.2z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-72.502 2.129C-72.502 2.129 -80.748 -1.389 -99.453 0.392C-99.453 0.392 -90.275 -0.897 -71.774 2.995C-61.62 5.131 -72.502 2.129 -72.502 2.129z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-70.714 2.222C-70.714 2.222 -78.676 -1.899 -97.461 -1.514C-97.461 -1.514 -88.213 -2.118 -70.052 3.14C-60.086 6.025 -70.714 2.222 -70.714 2.222z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-69.444 2.445C-69.444 2.445 -76.268 -1.862 -93.142 -2.96C-93.142 -2.96 -84.803 -2.79 -68.922 3.319C-60.206 6.672 -69.444 2.445 -69.444 2.445z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M45.84 12.961C45.84 12.961 44.91 13.605 45.124 12.424C45.339 11.243 73.547 -1.927 77.161 -1.677C77.161 -1.677 46.913 11.529 45.84 12.961z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M42.446 13.6C42.446 13.6 41.57 14.315 41.691 13.121C41.812 11.927 68.899 -3.418 72.521 -3.452C72.521 -3.452 43.404 12.089 42.446 13.6z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M39.16 14.975C39.16 14.975 38.332 15.747 38.374 14.547C38.416 13.348 58.233 -2.149 68.045 -4.023C68.045 -4.023 50.015 4.104 39.16 14.975z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M36.284 16.838C36.284 16.838 35.539 17.532 35.577 16.453C35.615 15.373 53.449 1.426 62.28 -0.26C62.28 -0.26 46.054 7.054 36.284 16.838z"/> + </g> + <g style="fill: #cccccc"> + <path d="M4.6 164.801C4.6 164.801 -10.6 162.401 6.2 160.801C6.2 160.801 24.2 158.801 28.2 153.601C28.2 153.601 41.8 144.401 44.6 144.001C47.4 143.601 63.8 140.001 64.2 137.601C64.6 135.201 70.6 132.801 72.2 133.601C73.8 134.401 73.8 143.601 71 144.401C68.2 145.201 49.4 152.401 43 153.601C36.6 154.801 25 162.401 20.2 163.601C15.4 164.801 4.6 164.801 4.6 164.801z"/> + </g> + <g style="fill: #000000"> + <path d="M77.6 127.401C77.6 127.401 74.6 129.001 73.4 131.601C73.4 131.601 67 142.201 52.8 145.401C52.8 145.401 29.8 154.401 22 156.401C22 156.401 8.6 161.401 1.2 160.601C1.2 160.601 -5.8 160.801 0.4 162.401C0.4 162.401 20.6 160.401 24 158.601C24 158.601 39.6 153.401 42.6 150.801C45.6 148.201 63.8 143.201 66 141.201C68.2 139.201 78 130.801 77.6 127.401z"/> + </g> + <g style="fill: #000000"> + <path d="M18.882 158.911C18.882 158.911 24.111 158.685 22.958 160.234C21.805 161.784 19.357 160.91 19.357 160.91L18.882 158.911z"/> + </g> + <g style="fill: #000000"> + <path d="M11.68 160.263C11.68 160.263 16.908 160.037 15.756 161.586C14.603 163.136 12.155 162.263 12.155 162.263L11.68 160.263z"/> + </g> + <g style="fill: #000000"> + <path d="M1.251 161.511C1.251 161.511 6.48 161.284 5.327 162.834C4.174 164.383 1.726 163.51 1.726 163.51L1.251 161.511z"/> + </g> + <g style="fill: #000000"> + <path d="M-6.383 162.055C-6.383 162.055 -1.154 161.829 -2.307 163.378C-3.46 164.928 -5.908 164.054 -5.908 164.054L-6.383 162.055z"/> + </g> + <g style="fill: #000000"> + <path d="M35.415 151.513C35.415 151.513 42.375 151.212 40.84 153.274C39.306 155.336 36.047 154.174 36.047 154.174L35.415 151.513z"/> + </g> + <g style="fill: #000000"> + <path d="M45.73 147.088C45.73 147.088 51.689 143.787 51.155 148.849C50.885 151.405 46.362 149.749 46.362 149.749L45.73 147.088z"/> + </g> + <g style="fill: #000000"> + <path d="M54.862 144.274C54.862 144.274 62.021 140.573 60.287 146.035C59.509 148.485 55.493 146.935 55.493 146.935L54.862 144.274z"/> + </g> + <g style="fill: #000000"> + <path d="M64.376 139.449C64.376 139.449 68.735 134.548 69.801 141.21C70.207 143.748 65.008 142.11 65.008 142.11L64.376 139.449z"/> + </g> + <g style="fill: #000000"> + <path d="M26.834 155.997C26.834 155.997 32.062 155.77 30.91 157.32C29.757 158.869 27.308 157.996 27.308 157.996L26.834 155.997z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M62.434 34.603C62.434 34.603 61.708 35.268 61.707 34.197C61.707 33.127 79.191 19.863 88.034 18.479C88.034 18.479 71.935 25.208 62.434 34.603z"/> + </g> + <g style="fill: #000000"> + <path d="M65.4 98.4C65.4 98.4 87.401 120.801 96.601 124.401C96.601 124.401 105.801 135.601 101.801 161.601C101.801 161.601 98.601 169.201 95.401 148.401C95.401 148.401 98.601 123.201 87.401 139.201C87.401 139.201 79 129.301 85.4 129.601C85.4 129.601 88.601 131.601 89.001 130.001C89.401 128.401 81.4 114.801 64.2 100.4C47 86 65.4 98.4 65.4 98.4z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M7 137.201C7 137.201 6.8 135.401 8.6 136.201C10.4 137.001 104.601 143.201 136.201 167.201C136.201 167.201 91.001 144.001 7 137.201z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M17.4 132.801C17.4 132.801 17.2 131.001 19 131.801C20.8 132.601 157.401 131.601 181.001 164.001C181.001 164.001 159.001 138.801 17.4 132.801z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M29 128.801C29 128.801 28.8 127.001 30.6 127.801C32.4 128.601 205.801 115.601 229.401 148.001C229.401 148.001 219.801 122.401 29 128.801z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M39 124.001C39 124.001 38.8 122.201 40.6 123.001C42.4 123.801 164.601 85.2 188.201 117.601C188.201 117.601 174.801 93 39 124.001z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-19 146.801C-19 146.801 -19.2 145.001 -17.4 145.801C-15.6 146.601 2.2 148.801 4.2 187.601C4.2 187.601 -3 145.601 -19 146.801z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-27.8 148.401C-27.8 148.401 -28 146.601 -26.2 147.401C-24.4 148.201 -10.2 143.601 -13 182.401C-13 182.401 -11.8 147.201 -27.8 148.401z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-35.8 148.801C-35.8 148.801 -36 147.001 -34.2 147.801C-32.4 148.601 -17 149.201 -29.4 171.601C-29.4 171.601 -19.8 147.601 -35.8 148.801z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M11.526 104.465C11.526 104.465 11.082 106.464 12.631 105.247C28.699 92.622 61.141 33.72 116.826 28.086C116.826 28.086 78.518 15.976 11.526 104.465z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M22.726 102.665C22.726 102.665 21.363 101.472 23.231 100.847C25.099 100.222 137.541 27.72 176.826 35.686C176.826 35.686 149.719 28.176 22.726 102.665z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M1.885 108.767C1.885 108.767 1.376 110.366 3.087 109.39C12.062 104.27 15.677 47.059 59.254 45.804C59.254 45.804 26.843 31.09 1.885 108.767z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-18.038 119.793C-18.038 119.793 -19.115 121.079 -17.162 120.825C-6.916 119.493 14.489 78.222 58.928 83.301C58.928 83.301 26.962 68.955 -18.038 119.793z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-6.8 113.667C-6.8 113.667 -7.611 115.136 -5.742 114.511C4.057 111.237 17.141 66.625 61.729 63.078C61.729 63.078 27.603 55.135 -6.8 113.667z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-25.078 124.912C-25.078 124.912 -25.951 125.954 -24.369 125.748C-16.07 124.669 1.268 91.24 37.264 95.354C37.264 95.354 11.371 83.734 -25.078 124.912z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-32.677 130.821C-32.677 130.821 -33.682 131.866 -32.091 131.748C-27.923 131.439 2.715 98.36 21.183 113.862C21.183 113.862 9.168 95.139 -32.677 130.821z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M36.855 98.898C36.855 98.898 35.654 97.543 37.586 97.158C39.518 96.774 160.221 39.061 198.184 51.927C198.184 51.927 172.243 41.053 36.855 98.898z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M3.4 163.201C3.4 163.201 3.2 161.401 5 162.201C6.8 163.001 22.2 163.601 9.8 186.001C9.8 186.001 19.4 162.001 3.4 163.201z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M13.8 161.601C13.8 161.601 13.6 159.801 15.4 160.601C17.2 161.401 35 163.601 37 202.401C37 202.401 29.8 160.401 13.8 161.601z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M20.6 160.001C20.6 160.001 20.4 158.201 22.2 159.001C24 159.801 48.6 163.201 72.2 195.601C72.2 195.601 36.6 158.801 20.6 160.001z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M28.225 157.972C28.225 157.972 27.788 156.214 29.678 156.768C31.568 157.322 52.002 155.423 90.099 189.599C90.099 189.599 43.924 154.656 28.225 157.972z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M38.625 153.572C38.625 153.572 38.188 151.814 40.078 152.368C41.968 152.922 76.802 157.423 128.499 192.399C128.499 192.399 54.324 150.256 38.625 153.572z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-1.8 142.001C-1.8 142.001 -2 140.201 -0.2 141.001C1.6 141.801 55 144.401 85.4 171.201C85.4 171.201 50.499 146.426 -1.8 142.001z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M-11.8 146.001C-11.8 146.001 -12 144.201 -10.2 145.001C-8.4 145.801 16.2 149.201 39.8 181.601C39.8 181.601 4.2 144.801 -11.8 146.001z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M49.503 148.962C49.503 148.962 48.938 147.241 50.864 147.655C52.79 148.068 87.86 150.004 141.981 181.098C141.981 181.098 64.317 146.704 49.503 148.962z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M57.903 146.562C57.903 146.562 57.338 144.841 59.264 145.255C61.19 145.668 96.26 147.604 150.381 178.698C150.381 178.698 73.317 143.904 57.903 146.562z"/> + </g> + <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1"> + <path d="M67.503 141.562C67.503 141.562 66.938 139.841 68.864 140.255C70.79 140.668 113.86 145.004 203.582 179.298C203.582 179.298 82.917 138.904 67.503 141.562z"/> + </g> + <g style="fill: #000000"> + <path d="M-43.8 148.401C-43.8 148.401 -38.6 148.001 -39.8 149.601C-41 151.201 -43.4 150.401 -43.4 150.401L-43.8 148.401z"/> + </g> + <g style="fill: #000000"> + <path d="M-13 162.401C-13 162.401 -7.8 162.001 -9 163.601C-10.2 165.201 -12.6 164.401 -12.6 164.401L-13 162.401z"/> + </g> + <g style="fill: #000000"> + <path d="M-21.8 162.001C-21.8 162.001 -16.6 161.601 -17.8 163.201C-19 164.801 -21.4 164.001 -21.4 164.001L-21.8 162.001z"/> + </g> + <g style="fill: #000000"> + <path d="M-117.169 150.182C-117.169 150.182 -112.124 151.505 -113.782 152.624C-115.439 153.744 -117.446 152.202 -117.446 152.202L-117.169 150.182z"/> + </g> + <g style="fill: #000000"> + <path d="M-115.169 140.582C-115.169 140.582 -110.124 141.905 -111.782 143.024C-113.439 144.144 -115.446 142.602 -115.446 142.602L-115.169 140.582z"/> + </g> + <g style="fill: #000000"> + <path d="M-122.369 136.182C-122.369 136.182 -117.324 137.505 -118.982 138.624C-120.639 139.744 -122.646 138.202 -122.646 138.202L-122.369 136.182z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-42.6 211.201C-42.6 211.201 -44.2 211.201 -48.2 213.201C-50.2 213.201 -61.4 216.801 -67 226.801C-67 226.801 -54.6 217.201 -42.6 211.201z"/> + </g> + <g style="fill: #cccccc"> + <path d="M45.116 303.847C45.257 304.105 45.312 304.525 45.604 304.542C46.262 304.582 47.495 304.883 47.37 304.247C46.522 299.941 45.648 295.004 41.515 293.197C40.876 292.918 39.434 293.331 39.36 294.215C39.233 295.739 39.116 297.088 39.425 298.554C39.725 299.975 41.883 299.985 42.8 298.601C43.736 300.273 44.168 302.116 45.116 303.847z"/> + </g> + <g style="fill: #cccccc"> + <path d="M34.038 308.581C34.786 309.994 34.659 311.853 36.074 312.416C36.814 312.71 38.664 311.735 38.246 310.661C37.444 308.6 37.056 306.361 35.667 304.55C35.467 304.288 35.707 303.755 35.547 303.427C34.953 302.207 33.808 301.472 32.4 301.801C31.285 304.004 32.433 306.133 33.955 307.842C34.091 307.994 33.925 308.37 34.038 308.581z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-5.564 303.391C-5.672 303.014 -5.71 302.551 -5.545 302.23C-5.014 301.197 -4.221 300.075 -4.558 299.053C-4.906 297.997 -6.022 298.179 -6.672 298.748C-7.807 299.742 -7.856 301.568 -8.547 302.927C-8.743 303.313 -8.692 303.886 -9.133 304.277C-9.607 304.698 -10.047 306.222 -9.951 306.793C-9.898 307.106 -10.081 317.014 -9.859 316.751C-9.24 316.018 -6.19 306.284 -6.121 305.392C-6.064 304.661 -5.332 304.196 -5.564 303.391z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-31.202 296.599C-28.568 294.1 -25.778 291.139 -26.22 287.427C-26.336 286.451 -28.111 286.978 -28.298 287.824C-29.1 291.449 -31.139 294.11 -33.707 296.502C-35.903 298.549 -37.765 304.893 -38 305.401C-34.303 300.145 -32.046 297.399 -31.202 296.599z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-44.776 290.635C-44.253 290.265 -44.555 289.774 -44.338 289.442C-43.385 287.984 -42.084 286.738 -42.066 285C-42.063 284.723 -42.441 284.414 -42.776 284.638C-43.053 284.822 -43.395 284.952 -43.503 285.082C-45.533 287.531 -46.933 290.202 -48.376 293.014C-48.559 293.371 -49.703 297.862 -49.39 297.973C-49.151 298.058 -47.431 293.877 -47.221 293.763C-45.958 293.077 -45.946 291.462 -44.776 290.635z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-28.043 310.179C-27.599 309.31 -26.023 308.108 -26.136 307.219C-26.254 306.291 -25.786 304.848 -26.698 305.536C-27.955 306.484 -31.404 307.833 -31.674 313.641C-31.7 314.212 -28.726 311.519 -28.043 310.179z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-13.6 293.001C-13.2 292.333 -12.492 292.806 -12.033 292.543C-11.385 292.171 -10.774 291.613 -10.482 290.964C-9.512 288.815 -7.743 286.995 -7.6 284.601C-9.091 283.196 -9.77 285.236 -10.4 286.201C-11.723 284.554 -12.722 286.428 -14.022 286.947C-14.092 286.975 -14.305 286.628 -14.38 286.655C-15.557 287.095 -16.237 288.176 -17.235 288.957C-17.406 289.091 -17.811 288.911 -17.958 289.047C-18.61 289.65 -19.583 289.975 -19.863 290.657C-20.973 293.364 -24.113 295.459 -26 303.001C-25.619 303.91 -21.488 296.359 -21.001 295.661C-20.165 294.465 -20.047 297.322 -18.771 296.656C-18.72 296.629 -18.534 296.867 -18.4 297.001C-18.206 296.721 -17.988 296.492 -17.6 296.601C-17.6 296.201 -17.734 295.645 -17.533 295.486C-16.296 294.509 -16.38 293.441 -15.6 292.201C-15.142 292.99 -14.081 292.271 -13.6 293.001z"/> + </g> + <g style="fill: #cccccc"> + <path d="M46.2 347.401C46.2 347.401 53.6 327.001 49.2 315.801C49.2 315.801 60.6 337.401 56 348.601C56 348.601 55.6 338.201 51.6 333.201C51.6 333.201 47.6 346.001 46.2 347.401z"/> + </g> + <g style="fill: #cccccc"> + <path d="M31.4 344.801C31.4 344.801 36.8 336.001 28.8 317.601C28.8 317.601 28 338.001 21.2 349.001C21.2 349.001 35.4 328.801 31.4 344.801z"/> + </g> + <g style="fill: #cccccc"> + <path d="M21.4 342.801C21.4 342.801 21.2 322.801 21.6 319.801C21.6 319.801 17.8 336.401 7.6 346.001C7.6 346.001 22 334.001 21.4 342.801z"/> + </g> + <g style="fill: #cccccc"> + <path d="M11.8 310.801C11.8 310.801 17.8 324.401 7.8 342.801C7.8 342.801 14.2 330.601 9.4 323.601C9.4 323.601 12 320.201 11.8 310.801z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-7.4 342.401C-7.4 342.401 -8.4 326.801 -6.6 324.601C-6.6 324.601 -6.4 318.201 -6.8 317.201C-6.8 317.201 -2.8 311.001 -2.6 318.401C-2.6 318.401 -1.2 326.201 1.6 330.801C1.6 330.801 5.2 336.201 5 342.601C5 342.601 -5 312.401 -7.4 342.401z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-11 314.801C-11 314.801 -17.6 325.601 -19.4 344.601C-19.4 344.601 -20.8 338.401 -17 324.001C-17 324.001 -12.8 308.601 -11 314.801z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-32.8 334.601C-32.8 334.601 -27.8 329.201 -26.4 324.201C-26.4 324.201 -22.8 308.401 -29.2 317.001C-29.2 317.001 -29 325.001 -37.2 332.401C-37.2 332.401 -32.4 330.001 -32.8 334.601z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-38.6 329.601C-38.6 329.601 -35.2 312.201 -34.4 311.401C-34.4 311.401 -32.6 308.001 -35.4 311.201C-35.4 311.201 -44.2 330.401 -48.2 337.001C-48.2 337.001 -40.2 327.801 -38.6 329.601z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-44.4 313.001C-44.4 313.001 -32.8 290.601 -54.6 316.401C-54.6 316.401 -43.6 306.601 -44.4 313.001z"/> + </g> + <g style="fill: #cccccc"> + <path d="M-59.8 298.401C-59.8 298.401 -55 279.601 -52.4 279.801C-52.4 279.801 -44.2 270.801 -50.8 281.401C-50.8 281.401 -56.8 291.001 -56.2 300.801C-56.2 300.801 -56.8 291.201 -59.8 298.401z"/> + </g> + <g style="fill: #cccccc"> + <path d="M270.5 287C270.5 287 258.5 277 256 273.5C256 273.5 269.5 292 269.5 299C269.5 299 272 291.5 270.5 287z"/> + </g> + <g style="fill: #cccccc"> + <path d="M276 265C276 265 255 250 251.5 242.5C251.5 242.5 278 272 278 276.5C278 276.5 278.5 267.5 276 265z"/> + </g> + <g style="fill: #cccccc"> + <path d="M293 111C293 111 281 103 279.5 105C279.5 105 290 111.5 292.5 120C292.5 120 291 111 293 111z"/> + </g> + <g style="fill: #cccccc"> + <path d="M301.5 191.5L284 179.5C284 179.5 303 196.5 303.5 200.5L301.5 191.5z"/> + </g> + <g style="stroke:#000000"> + <path d="M-89.25 169L-67.25 173.75"/> + </g> + <g style="stroke:#000000"> + <path d="M-39 331C-39 331 -39.5 327.5 -48.5 338"/> + </g> + <g style="stroke:#000000"> + <path d="M-33.5 336C-33.5 336 -31.5 329.5 -38 334"/> + </g> + <g style="stroke:#000000"> + <path d="M20.5 344.5C20.5 344.5 22 333.5 10.5 346.5"/> + </g> +</g> +</svg> diff --git a/src/corelib/render/software/ctrl/agg_bezier_ctrl.pas b/src/corelib/render/software/ctrl/agg_bezier_ctrl.pas index 6f158c2b..2b92baa3 100644 --- a/src/corelib/render/software/ctrl/agg_bezier_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_bezier_ctrl.pas @@ -1,887 +1,887 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-//----------------------------------------------------------------------------
-//
-// classes bezier_ctrl_impl, bezier_ctrl
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 23.02.2006-Milano: Unit port establishment
-//
-{ agg_bezier_ctrl.pas }
-unit
- agg_bezier_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- agg_basics ,
- agg_ctrl ,
- agg_math ,
- agg_ellipse ,
- agg_trans_affine ,
- agg_color ,
- agg_curves ,
- agg_conv_stroke ,
- agg_conv_curve ,
- agg_polygon_ctrl ;
-
-{ TYPES DEFINITION }
-type
- bezier_ctrl_impl = object(ctrl )
- m_curve : curve4;
- m_ellipse : ellipse;
- m_stroke : conv_stroke;
- m_poly : polygon_ctrl_impl;
- m_idx : unsigned;
-
- constructor Construct;
- destructor Destruct; virtual;
-
- procedure curve_(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double );
- function _curve : curve4_ptr;
-
- function _x1 : double;
- function _y1 : double;
- function _x2 : double;
- function _y2 : double;
- function _x3 : double;
- function _y3 : double;
- function _x4 : double;
- function _y4 : double;
-
- procedure x1_(x : double );
- procedure y1_(y : double );
- procedure x2_(x : double );
- procedure y2_(y : double );
- procedure x3_(x : double );
- procedure y3_(y : double );
- procedure x4_(x : double );
- procedure y4_(y : double );
-
- procedure line_width_(w : double );
- function _line_width : double;
-
- procedure point_radius_(r : double );
- function _point_radius : double;
-
- // Event handlers
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- // Vertex source interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- end;
-
- bezier_ctrl = object(bezier_ctrl_impl )
- m_color : aggclr;
-
- constructor Construct;
-
- procedure line_color_(c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
- curve3_ctrl_impl = object(ctrl )
- m_curve : curve3;
- m_ellipse : ellipse;
- m_stroke : conv_stroke;
- m_poly : polygon_ctrl_impl;
- m_idx : unsigned;
-
- constructor Construct;
- destructor Destruct; virtual;
-
- procedure curve_(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
- function _curve : curve3_ptr;
-
- function _x1 : double;
- function _y1 : double;
- function _x2 : double;
- function _y2 : double;
- function _x3 : double;
- function _y3 : double;
-
- procedure x1_(x : double );
- procedure y1_(y : double );
- procedure x2_(x : double );
- procedure y2_(y : double );
- procedure x3_(x : double );
- procedure y3_(y : double );
-
- procedure line_width_(w : double );
- function _line_width : double;
-
- procedure point_radius_(r : double );
- function _point_radius : double;
-
- // Event handlers
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- // Vertex source interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- end;
-
- curve3_ctrl = object(curve3_ctrl_impl )
- m_color : aggclr;
-
- constructor Construct;
-
- procedure line_color_(c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor bezier_ctrl_impl.Construct;
-begin
- inherited Construct(0 ,0 ,1 ,1 ,false );
-
- m_curve.Construct;
- m_ellipse.Construct;
- m_stroke.Construct(@m_curve );
- m_poly.Construct (4 ,5.0 );
-
- m_idx:=0;
-
- m_poly.in_polygon_check_(false );
-
- m_poly.xn_ptr(0 )^:=100.0;
- m_poly.yn_ptr(0 )^:= 0.0;
- m_poly.xn_ptr(1 )^:=100.0;
- m_poly.yn_ptr(1 )^:= 50.0;
- m_poly.xn_ptr(2 )^:= 50.0;
- m_poly.yn_ptr(2 )^:=100.0;
- m_poly.xn_ptr(3 )^:= 0.0;
- m_poly.yn_ptr(3 )^:=100.0;
-
-end;
-
-{ DESTRUCT }
-destructor bezier_ctrl_impl.Destruct;
-begin
- m_curve.Destruct;
- m_stroke.Destruct;
- m_poly.Destruct;
-
-end;
-
-{ CURVE_ }
-procedure bezier_ctrl_impl.curve_;
-begin
- m_poly.xn_ptr(0 )^:=x1;
- m_poly.yn_ptr(0 )^:=y1;
- m_poly.xn_ptr(1 )^:=x2;
- m_poly.yn_ptr(1 )^:=y2;
- m_poly.xn_ptr(2 )^:=x3;
- m_poly.yn_ptr(2 )^:=y3;
- m_poly.xn_ptr(3 )^:=x4;
- m_poly.yn_ptr(3 )^:=y4;
-
- _curve;
-
-end;
-
-{ _CURVE }
-function bezier_ctrl_impl._curve;
-begin
- m_curve.init4(
- m_poly._xn(0 ) ,m_poly._yn(0 ) ,
- m_poly._xn(1 ) ,m_poly._yn(1 ) ,
- m_poly._xn(2 ) ,m_poly._yn(2 ) ,
- m_poly._xn(3 ) ,m_poly._yn(3 ) );
-
- result:=@m_curve;
-
-end;
-
-{ _X1 }
-function bezier_ctrl_impl._x1;
-begin
- result:=m_poly._xn(0 );
-
-end;
-
-{ _Y1 }
-function bezier_ctrl_impl._y1;
-begin
- result:=m_poly._yn(0 );
-
-end;
-
-{ _X2 }
-function bezier_ctrl_impl._x2;
-begin
- result:=m_poly._xn(1 );
-
-end;
-
-{ _Y2 }
-function bezier_ctrl_impl._y2;
-begin
- result:=m_poly._yn(1 );
-
-end;
-
-{ _X3 }
-function bezier_ctrl_impl._x3;
-begin
- result:=m_poly._xn(2 );
-
-end;
-
-{ _Y3 }
-function bezier_ctrl_impl._y3;
-begin
- result:=m_poly._yn(2 );
-
-end;
-
-{ _X4 }
-function bezier_ctrl_impl._x4;
-begin
- result:=m_poly._xn(3 );
-
-end;
-
-{ _Y4 }
-function bezier_ctrl_impl._y4;
-begin
- result:=m_poly._yn(3 );
-
-end;
-
-{ X1_ }
-procedure bezier_ctrl_impl.x1_;
-begin
- m_poly.xn_ptr(0 )^:=x;
-
-end;
-
-{ Y1_ }
-procedure bezier_ctrl_impl.y1_;
-begin
- m_poly.yn_ptr(0 )^:=y;
-
-end;
-
-{ X2_ }
-procedure bezier_ctrl_impl.x2_;
-begin
- m_poly.xn_ptr(1 )^:=x;
-
-end;
-
-{ Y2_ }
-procedure bezier_ctrl_impl.y2_;
-begin
- m_poly.yn_ptr(1 )^:=y;
-
-end;
-
-{ X3_ }
-procedure bezier_ctrl_impl.x3_;
-begin
- m_poly.xn_ptr(2 )^:=x;
-
-end;
-
-{ Y3_ }
-procedure bezier_ctrl_impl.y3_;
-begin
- m_poly.yn_ptr(2 )^:=y;
-
-end;
-
-{ X4_ }
-procedure bezier_ctrl_impl.x4_;
-begin
- m_poly.xn_ptr(3 )^:=x;
-
-end;
-
-{ Y4_ }
-procedure bezier_ctrl_impl.y4_;
-begin
- m_poly.yn_ptr(3 )^:=y;
-
-end;
-
-{ LINE_WIDTH_ }
-procedure bezier_ctrl_impl.line_width_;
-begin
- m_stroke.width_(w );
-
-end;
-
-{ _LINE_WIDTH }
-function bezier_ctrl_impl._line_width;
-begin
- result:=m_stroke._width;
-
-end;
-
-{ POINT_RADIUS_ }
-procedure bezier_ctrl_impl.point_radius_;
-begin
- m_poly.point_radius_(r );
-
-end;
-
-{ _POINT_RADIUS }
-function bezier_ctrl_impl._point_radius;
-begin
- result:=m_poly._point_radius;
-
-end;
-
-{ IN_RECT }
-function bezier_ctrl_impl.in_rect;
-begin
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function bezier_ctrl_impl.on_mouse_button_down;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=m_poly.on_mouse_button_down(x ,y );
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function bezier_ctrl_impl.on_mouse_button_up;
-begin
- result:=m_poly.on_mouse_button_up(x ,y );
-
-end;
-
-{ ON_MOUSE_MOVE }
-function bezier_ctrl_impl.on_mouse_move;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=m_poly.on_mouse_move(x ,y ,button_flag );
-
-end;
-
-{ ON_ARROW_KEYS }
-function bezier_ctrl_impl.on_arrow_keys;
-begin
- result:=m_poly.on_arrow_keys(left ,right ,down ,up );
-
-end;
-
-{ NUM_PATHS }
-function bezier_ctrl_impl.num_paths;
-begin
- result:=7;
-
-end;
-
-{ REWIND }
-procedure bezier_ctrl_impl.rewind;
-begin
- m_idx:=path_id;
-
- m_curve.approximation_scale_(scale );
-
- case path_id of
- 0 : // Control line 1
- begin
- m_curve.init4(
- m_poly._xn(0 ) ,m_poly._yn(0 ) ,
- (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5 ,
- (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5 ,
- (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5 ,
- (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5 ,
- m_poly._xn(1 ) ,m_poly._yn(1 ) );
-
- m_stroke.rewind(0 );
-
- end;
-
- 1 : // Control line 2
- begin
- m_curve.init4(
- m_poly._xn(2 ) ,m_poly._yn(2 ) ,
- (m_poly._xn(2 ) + m_poly._xn(3 ) ) * 0.5,
- (m_poly._yn(2 ) + m_poly._yn(3 ) ) * 0.5,
- (m_poly._xn(2 ) + m_poly._xn(3 ) ) * 0.5,
- (m_poly._yn(2 ) + m_poly._yn(3 ) ) * 0.5,
- m_poly._xn(3 ) ,m_poly._yn(3 ) );
-
- m_stroke.rewind(0 );
-
- end;
-
- 2 : // Curve itself
- begin
- m_curve.init4(
- m_poly._xn(0 ) ,m_poly._yn(0 ) ,
- m_poly._xn(1 ) ,m_poly._yn(1 ) ,
- m_poly._xn(2 ) ,m_poly._yn(2 ) ,
- m_poly._xn(3 ) ,m_poly._yn(3 ) );
-
- m_stroke.rewind(0 );
-
- end;
-
- 3 : // Point 1
- begin
- m_ellipse.init (m_poly._xn(0 ) ,m_poly._yn(0 ) ,_point_radius ,_point_radius ,20 );
- m_ellipse.rewind(0 );
-
- end;
-
- 4 : // Point 2
- begin
- m_ellipse.init (m_poly._xn(1 ) ,m_poly._yn(1 ) ,_point_radius ,_point_radius ,20 );
- m_ellipse.rewind(0 );
-
- end;
-
- 5 : // Point 3
- begin
- m_ellipse.init (m_poly._xn(2 ) ,m_poly._yn(2 ) ,_point_radius ,_point_radius ,20 );
- m_ellipse.rewind(0 );
-
- end;
-
- 6 : // Point 4
- begin
- m_ellipse.init (m_poly._xn(3 ) ,m_poly._yn(3 ) ,_point_radius ,_point_radius ,20 );
- m_ellipse.rewind(0 );
-
- end;
-
- end;
-
-end;
-
-{ VERTEX }
-function bezier_ctrl_impl.vertex;
-var
- cmd : unsigned;
-
-begin
- cmd:=path_cmd_stop;
-
- case m_idx of
- 0 ,1 ,2 :
- cmd:=m_stroke.vertex(x ,y );
-
- 3 ,4 ,5 ,6 ,7 :
- cmd:=m_ellipse.vertex(x, y);
-
- end;
-
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ CONSTRUCT }
-constructor bezier_ctrl.Construct;
-begin
- inherited Construct;
-
- m_color.ConstrDbl(0.0 ,0.0 ,0.0 );
-
-end;
-
-{ LINE_COLOR_ }
-procedure bezier_ctrl.line_color_;
-begin
- m_color:=c^;
-
-end;
-
-{ _COLOR }
-function bezier_ctrl._color;
-begin
- result:=@m_color;
-
-end;
-
-{ CONSTRUCT }
-constructor curve3_ctrl_impl.Construct;
-begin
- inherited Construct(0 ,0 ,1 ,1 ,false );
-
- m_curve.Construct;
- m_ellipse.Construct;
- m_stroke.Construct(@m_curve );
- m_poly.Construct (3 ,5.0 );
-
- m_idx:=0;
-
- m_poly.in_polygon_check_(false );
-
- m_poly.xn_ptr(0 )^:=100.0;
- m_poly.yn_ptr(0 )^:= 0.0;
- m_poly.xn_ptr(1 )^:=100.0;
- m_poly.yn_ptr(1 )^:= 50.0;
- m_poly.xn_ptr(2 )^:= 50.0;
- m_poly.yn_ptr(2 )^:=100.0;
-
-end;
-
-{ DESTRUCT }
-destructor curve3_ctrl_impl.Destruct;
-begin
- m_curve.Destruct;
- m_stroke.Destruct;
- m_poly.Destruct;
-
-end;
-
-{ CURVE_ }
-procedure curve3_ctrl_impl.curve_;
-begin
- m_poly.xn_ptr(0 )^:=x1;
- m_poly.yn_ptr(0 )^:=y1;
- m_poly.xn_ptr(1 )^:=x2;
- m_poly.yn_ptr(1 )^:=y2;
- m_poly.xn_ptr(2 )^:=x3;
- m_poly.yn_ptr(2 )^:=y3;
-
- _curve;
-
-end;
-
-{ _CURVE }
-function curve3_ctrl_impl._curve;
-begin
- m_curve.init3(
- m_poly._xn(0 ) ,m_poly._yn(0 ) ,
- m_poly._xn(1 ) ,m_poly._yn(1 ) ,
- m_poly._xn(2 ) ,m_poly._yn(2 ) );
-
- result:=@m_curve;
-
-end;
-
-{ _X1 }
-function curve3_ctrl_impl._x1;
-begin
- result:=m_poly._xn(0 );
-
-end;
-
-{ _Y1 }
-function curve3_ctrl_impl._y1;
-begin
- result:=m_poly._yn(0 );
-
-end;
-
-{ _X2 }
-function curve3_ctrl_impl._x2;
-begin
- result:=m_poly._xn(1 );
-
-end;
-
-{ _Y2 }
-function curve3_ctrl_impl._y2;
-begin
- result:=m_poly._yn(1 );
-
-end;
-
-{ _X3 }
-function curve3_ctrl_impl._x3;
-begin
- result:=m_poly._xn(2 );
-
-end;
-
-{ _Y3 }
-function curve3_ctrl_impl._y3;
-begin
- result:=m_poly._yn(2 );
-
-end;
-
-{ X1_ }
-procedure curve3_ctrl_impl.x1_;
-begin
- m_poly.xn_ptr(0 )^:=x;
-
-end;
-
-{ Y1_ }
-procedure curve3_ctrl_impl.y1_;
-begin
- m_poly.yn_ptr(0 )^:=y;
-
-end;
-
-{ X2_ }
-procedure curve3_ctrl_impl.x2_;
-begin
- m_poly.xn_ptr(1 )^:=x;
-
-end;
-
-{ Y2_ }
-procedure curve3_ctrl_impl.y2_;
-begin
- m_poly.yn_ptr(1 )^:=y;
-
-end;
-
-{ X3_ }
-procedure curve3_ctrl_impl.x3_;
-begin
- m_poly.xn_ptr(2 )^:=x;
-
-end;
-
-{ Y3_ }
-procedure curve3_ctrl_impl.y3_;
-begin
- m_poly.yn_ptr(2 )^:=y;
-
-end;
-
-{ LINE_WIDTH_ }
-procedure curve3_ctrl_impl.line_width_;
-begin
- m_stroke.width_(w );
-
-end;
-
-{ _LINE_WIDTH }
-function curve3_ctrl_impl._line_width;
-begin
- result:=m_stroke._width;
-
-end;
-
-{ POINT_RADIUS_ }
-procedure curve3_ctrl_impl.point_radius_;
-begin
- m_poly.point_radius_(r );
-
-end;
-
-{ _POINT_RADIUS }
-function curve3_ctrl_impl._point_radius;
-begin
- result:=m_poly._point_radius;
-
-end;
-
-{ IN_RECT }
-function curve3_ctrl_impl.in_rect;
-begin
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function curve3_ctrl_impl.on_mouse_button_down;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=m_poly.on_mouse_button_down(x ,y );
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function curve3_ctrl_impl.on_mouse_button_up;
-begin
- result:=m_poly.on_mouse_button_up(x ,y );
-
-end;
-
-{ ON_MOUSE_MOVE }
-function curve3_ctrl_impl.on_mouse_move;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=m_poly.on_mouse_move(x ,y ,button_flag );
-
-end;
-
-{ ON_ARROW_KEYS }
-function curve3_ctrl_impl.on_arrow_keys;
-begin
- result:=m_poly.on_arrow_keys(left ,right ,down ,up );
-
-end;
-
-{ NUM_PATHS }
-function curve3_ctrl_impl.num_paths;
-begin
- result:=6;
-
-end;
-
-{ REWIND }
-procedure curve3_ctrl_impl.rewind;
-begin
- m_idx:=path_id;
-
- case path_id of
- 0 : // Control line
- begin
- m_curve.init3(
- m_poly._xn(0 ) ,m_poly._yn(0 ) ,
- (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5,
- (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5,
- m_poly._xn(1 ) ,m_poly._yn(1 ) );
-
- m_stroke.rewind(0 );
-
- end;
-
- 1 : // Control line 2
- begin
- m_curve.init3(
- m_poly._xn(1 ) ,m_poly._yn(1 ) ,
- (m_poly._xn(1 ) + m_poly._xn(2 ) ) * 0.5,
- (m_poly._yn(1 ) + m_poly._yn(2 ) ) * 0.5,
- m_poly._xn(2 ) ,m_poly._yn(2 ) );
-
- m_stroke.rewind(0 );
-
- end;
-
- 2 : // Curve itself
- begin
- m_curve.init3(
- m_poly._xn(0 ) ,m_poly._yn(0 ) ,
- m_poly._xn(1 ) ,m_poly._yn(1 ) ,
- m_poly._xn(2 ) ,m_poly._yn(2 ) );
-
- m_stroke.rewind(0 );
-
- end;
-
- 3 : // Point 1
- begin
- m_ellipse.init (m_poly._xn(0 ) ,m_poly._yn(0 ) ,_point_radius ,_point_radius ,20 );
- m_ellipse.rewind(0 );
-
- end;
-
- 4 : // Point 2
- begin
- m_ellipse.init (m_poly._xn(1 ) ,m_poly._yn(1 ) ,_point_radius ,_point_radius ,20 );
- m_ellipse.rewind(0 );
-
- end;
-
- 5 : // Point 3
- begin
- m_ellipse.init (m_poly._xn(2 ) ,m_poly._yn(2 ) ,_point_radius ,_point_radius ,20 );
- m_ellipse.rewind(0 );
-
- end;
-
- end;
-
-end;
-
-{ VERTEX }
-function curve3_ctrl_impl.vertex;
-var
- cmd : unsigned;
-
-begin
- cmd:=path_cmd_stop;
-
- case m_idx of
- 0 ,1 ,2 :
- cmd:=m_stroke.vertex(x ,y );
-
- 3 ,4 ,5 ,6 :
- cmd:=m_ellipse.vertex(x ,y );
-
- end;
-
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ CONSTRUCT }
-constructor curve3_ctrl.Construct;
-begin
- inherited Construct;
-
- m_color.ConstrDbl(0.0 ,0.0 ,0.0 );
-
-end;
-
-{ LINE_COLOR_ }
-procedure curve3_ctrl.line_color_;
-begin
- m_color:=c^;
-
-end;
-
-{ _COLOR }
-function curve3_ctrl._color;
-begin
- result:=@m_color;
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +//---------------------------------------------------------------------------- +// +// classes bezier_ctrl_impl, bezier_ctrl +// +// [Pascal Port History] ----------------------------------------------------- +// +// 23.02.2006-Milano: Unit port establishment +// +{ agg_bezier_ctrl.pas } +unit + agg_bezier_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + agg_basics , + agg_ctrl , + agg_math , + agg_ellipse , + agg_trans_affine , + agg_color , + agg_curves , + agg_conv_stroke , + agg_conv_curve , + agg_polygon_ctrl ; + +{ TYPES DEFINITION } +type + bezier_ctrl_impl = object(ctrl ) + m_curve : curve4; + m_ellipse : ellipse; + m_stroke : conv_stroke; + m_poly : polygon_ctrl_impl; + m_idx : unsigned; + + constructor Construct; + destructor Destruct; virtual; + + procedure curve_(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double ); + function _curve : curve4_ptr; + + function _x1 : double; + function _y1 : double; + function _x2 : double; + function _y2 : double; + function _x3 : double; + function _y3 : double; + function _x4 : double; + function _y4 : double; + + procedure x1_(x : double ); + procedure y1_(y : double ); + procedure x2_(x : double ); + procedure y2_(y : double ); + procedure x3_(x : double ); + procedure y3_(y : double ); + procedure x4_(x : double ); + procedure y4_(y : double ); + + procedure line_width_(w : double ); + function _line_width : double; + + procedure point_radius_(r : double ); + function _point_radius : double; + + // Event handlers + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Vertex source interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + end; + + bezier_ctrl = object(bezier_ctrl_impl ) + m_color : aggclr; + + constructor Construct; + + procedure line_color_(c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + + curve3_ctrl_impl = object(ctrl ) + m_curve : curve3; + m_ellipse : ellipse; + m_stroke : conv_stroke; + m_poly : polygon_ctrl_impl; + m_idx : unsigned; + + constructor Construct; + destructor Destruct; virtual; + + procedure curve_(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double ); + function _curve : curve3_ptr; + + function _x1 : double; + function _y1 : double; + function _x2 : double; + function _y2 : double; + function _x3 : double; + function _y3 : double; + + procedure x1_(x : double ); + procedure y1_(y : double ); + procedure x2_(x : double ); + procedure y2_(y : double ); + procedure x3_(x : double ); + procedure y3_(y : double ); + + procedure line_width_(w : double ); + function _line_width : double; + + procedure point_radius_(r : double ); + function _point_radius : double; + + // Event handlers + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Vertex source interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + end; + + curve3_ctrl = object(curve3_ctrl_impl ) + m_color : aggclr; + + constructor Construct; + + procedure line_color_(c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor bezier_ctrl_impl.Construct; +begin + inherited Construct(0 ,0 ,1 ,1 ,false ); + + m_curve.Construct; + m_ellipse.Construct; + m_stroke.Construct(@m_curve ); + m_poly.Construct (4 ,5.0 ); + + m_idx:=0; + + m_poly.in_polygon_check_(false ); + + m_poly.xn_ptr(0 )^:=100.0; + m_poly.yn_ptr(0 )^:= 0.0; + m_poly.xn_ptr(1 )^:=100.0; + m_poly.yn_ptr(1 )^:= 50.0; + m_poly.xn_ptr(2 )^:= 50.0; + m_poly.yn_ptr(2 )^:=100.0; + m_poly.xn_ptr(3 )^:= 0.0; + m_poly.yn_ptr(3 )^:=100.0; + +end; + +{ DESTRUCT } +destructor bezier_ctrl_impl.Destruct; +begin + m_curve.Destruct; + m_stroke.Destruct; + m_poly.Destruct; + +end; + +{ CURVE_ } +procedure bezier_ctrl_impl.curve_; +begin + m_poly.xn_ptr(0 )^:=x1; + m_poly.yn_ptr(0 )^:=y1; + m_poly.xn_ptr(1 )^:=x2; + m_poly.yn_ptr(1 )^:=y2; + m_poly.xn_ptr(2 )^:=x3; + m_poly.yn_ptr(2 )^:=y3; + m_poly.xn_ptr(3 )^:=x4; + m_poly.yn_ptr(3 )^:=y4; + + _curve; + +end; + +{ _CURVE } +function bezier_ctrl_impl._curve; +begin + m_curve.init4( + m_poly._xn(0 ) ,m_poly._yn(0 ) , + m_poly._xn(1 ) ,m_poly._yn(1 ) , + m_poly._xn(2 ) ,m_poly._yn(2 ) , + m_poly._xn(3 ) ,m_poly._yn(3 ) ); + + result:=@m_curve; + +end; + +{ _X1 } +function bezier_ctrl_impl._x1; +begin + result:=m_poly._xn(0 ); + +end; + +{ _Y1 } +function bezier_ctrl_impl._y1; +begin + result:=m_poly._yn(0 ); + +end; + +{ _X2 } +function bezier_ctrl_impl._x2; +begin + result:=m_poly._xn(1 ); + +end; + +{ _Y2 } +function bezier_ctrl_impl._y2; +begin + result:=m_poly._yn(1 ); + +end; + +{ _X3 } +function bezier_ctrl_impl._x3; +begin + result:=m_poly._xn(2 ); + +end; + +{ _Y3 } +function bezier_ctrl_impl._y3; +begin + result:=m_poly._yn(2 ); + +end; + +{ _X4 } +function bezier_ctrl_impl._x4; +begin + result:=m_poly._xn(3 ); + +end; + +{ _Y4 } +function bezier_ctrl_impl._y4; +begin + result:=m_poly._yn(3 ); + +end; + +{ X1_ } +procedure bezier_ctrl_impl.x1_; +begin + m_poly.xn_ptr(0 )^:=x; + +end; + +{ Y1_ } +procedure bezier_ctrl_impl.y1_; +begin + m_poly.yn_ptr(0 )^:=y; + +end; + +{ X2_ } +procedure bezier_ctrl_impl.x2_; +begin + m_poly.xn_ptr(1 )^:=x; + +end; + +{ Y2_ } +procedure bezier_ctrl_impl.y2_; +begin + m_poly.yn_ptr(1 )^:=y; + +end; + +{ X3_ } +procedure bezier_ctrl_impl.x3_; +begin + m_poly.xn_ptr(2 )^:=x; + +end; + +{ Y3_ } +procedure bezier_ctrl_impl.y3_; +begin + m_poly.yn_ptr(2 )^:=y; + +end; + +{ X4_ } +procedure bezier_ctrl_impl.x4_; +begin + m_poly.xn_ptr(3 )^:=x; + +end; + +{ Y4_ } +procedure bezier_ctrl_impl.y4_; +begin + m_poly.yn_ptr(3 )^:=y; + +end; + +{ LINE_WIDTH_ } +procedure bezier_ctrl_impl.line_width_; +begin + m_stroke.width_(w ); + +end; + +{ _LINE_WIDTH } +function bezier_ctrl_impl._line_width; +begin + result:=m_stroke._width; + +end; + +{ POINT_RADIUS_ } +procedure bezier_ctrl_impl.point_radius_; +begin + m_poly.point_radius_(r ); + +end; + +{ _POINT_RADIUS } +function bezier_ctrl_impl._point_radius; +begin + result:=m_poly._point_radius; + +end; + +{ IN_RECT } +function bezier_ctrl_impl.in_rect; +begin + result:=false; + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function bezier_ctrl_impl.on_mouse_button_down; +begin + inverse_transform_xy(@x ,@y ); + + result:=m_poly.on_mouse_button_down(x ,y ); + +end; + +{ ON_MOUSE_BUTTON_UP } +function bezier_ctrl_impl.on_mouse_button_up; +begin + result:=m_poly.on_mouse_button_up(x ,y ); + +end; + +{ ON_MOUSE_MOVE } +function bezier_ctrl_impl.on_mouse_move; +begin + inverse_transform_xy(@x ,@y ); + + result:=m_poly.on_mouse_move(x ,y ,button_flag ); + +end; + +{ ON_ARROW_KEYS } +function bezier_ctrl_impl.on_arrow_keys; +begin + result:=m_poly.on_arrow_keys(left ,right ,down ,up ); + +end; + +{ NUM_PATHS } +function bezier_ctrl_impl.num_paths; +begin + result:=7; + +end; + +{ REWIND } +procedure bezier_ctrl_impl.rewind; +begin + m_idx:=path_id; + + m_curve.approximation_scale_(scale ); + + case path_id of + 0 : // Control line 1 + begin + m_curve.init4( + m_poly._xn(0 ) ,m_poly._yn(0 ) , + (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5 , + (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5 , + (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5 , + (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5 , + m_poly._xn(1 ) ,m_poly._yn(1 ) ); + + m_stroke.rewind(0 ); + + end; + + 1 : // Control line 2 + begin + m_curve.init4( + m_poly._xn(2 ) ,m_poly._yn(2 ) , + (m_poly._xn(2 ) + m_poly._xn(3 ) ) * 0.5, + (m_poly._yn(2 ) + m_poly._yn(3 ) ) * 0.5, + (m_poly._xn(2 ) + m_poly._xn(3 ) ) * 0.5, + (m_poly._yn(2 ) + m_poly._yn(3 ) ) * 0.5, + m_poly._xn(3 ) ,m_poly._yn(3 ) ); + + m_stroke.rewind(0 ); + + end; + + 2 : // Curve itself + begin + m_curve.init4( + m_poly._xn(0 ) ,m_poly._yn(0 ) , + m_poly._xn(1 ) ,m_poly._yn(1 ) , + m_poly._xn(2 ) ,m_poly._yn(2 ) , + m_poly._xn(3 ) ,m_poly._yn(3 ) ); + + m_stroke.rewind(0 ); + + end; + + 3 : // Point 1 + begin + m_ellipse.init (m_poly._xn(0 ) ,m_poly._yn(0 ) ,_point_radius ,_point_radius ,20 ); + m_ellipse.rewind(0 ); + + end; + + 4 : // Point 2 + begin + m_ellipse.init (m_poly._xn(1 ) ,m_poly._yn(1 ) ,_point_radius ,_point_radius ,20 ); + m_ellipse.rewind(0 ); + + end; + + 5 : // Point 3 + begin + m_ellipse.init (m_poly._xn(2 ) ,m_poly._yn(2 ) ,_point_radius ,_point_radius ,20 ); + m_ellipse.rewind(0 ); + + end; + + 6 : // Point 4 + begin + m_ellipse.init (m_poly._xn(3 ) ,m_poly._yn(3 ) ,_point_radius ,_point_radius ,20 ); + m_ellipse.rewind(0 ); + + end; + + end; + +end; + +{ VERTEX } +function bezier_ctrl_impl.vertex; +var + cmd : unsigned; + +begin + cmd:=path_cmd_stop; + + case m_idx of + 0 ,1 ,2 : + cmd:=m_stroke.vertex(x ,y ); + + 3 ,4 ,5 ,6 ,7 : + cmd:=m_ellipse.vertex(x, y); + + end; + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ CONSTRUCT } +constructor bezier_ctrl.Construct; +begin + inherited Construct; + + m_color.ConstrDbl(0.0 ,0.0 ,0.0 ); + +end; + +{ LINE_COLOR_ } +procedure bezier_ctrl.line_color_; +begin + m_color:=c^; + +end; + +{ _COLOR } +function bezier_ctrl._color; +begin + result:=@m_color; + +end; + +{ CONSTRUCT } +constructor curve3_ctrl_impl.Construct; +begin + inherited Construct(0 ,0 ,1 ,1 ,false ); + + m_curve.Construct; + m_ellipse.Construct; + m_stroke.Construct(@m_curve ); + m_poly.Construct (3 ,5.0 ); + + m_idx:=0; + + m_poly.in_polygon_check_(false ); + + m_poly.xn_ptr(0 )^:=100.0; + m_poly.yn_ptr(0 )^:= 0.0; + m_poly.xn_ptr(1 )^:=100.0; + m_poly.yn_ptr(1 )^:= 50.0; + m_poly.xn_ptr(2 )^:= 50.0; + m_poly.yn_ptr(2 )^:=100.0; + +end; + +{ DESTRUCT } +destructor curve3_ctrl_impl.Destruct; +begin + m_curve.Destruct; + m_stroke.Destruct; + m_poly.Destruct; + +end; + +{ CURVE_ } +procedure curve3_ctrl_impl.curve_; +begin + m_poly.xn_ptr(0 )^:=x1; + m_poly.yn_ptr(0 )^:=y1; + m_poly.xn_ptr(1 )^:=x2; + m_poly.yn_ptr(1 )^:=y2; + m_poly.xn_ptr(2 )^:=x3; + m_poly.yn_ptr(2 )^:=y3; + + _curve; + +end; + +{ _CURVE } +function curve3_ctrl_impl._curve; +begin + m_curve.init3( + m_poly._xn(0 ) ,m_poly._yn(0 ) , + m_poly._xn(1 ) ,m_poly._yn(1 ) , + m_poly._xn(2 ) ,m_poly._yn(2 ) ); + + result:=@m_curve; + +end; + +{ _X1 } +function curve3_ctrl_impl._x1; +begin + result:=m_poly._xn(0 ); + +end; + +{ _Y1 } +function curve3_ctrl_impl._y1; +begin + result:=m_poly._yn(0 ); + +end; + +{ _X2 } +function curve3_ctrl_impl._x2; +begin + result:=m_poly._xn(1 ); + +end; + +{ _Y2 } +function curve3_ctrl_impl._y2; +begin + result:=m_poly._yn(1 ); + +end; + +{ _X3 } +function curve3_ctrl_impl._x3; +begin + result:=m_poly._xn(2 ); + +end; + +{ _Y3 } +function curve3_ctrl_impl._y3; +begin + result:=m_poly._yn(2 ); + +end; + +{ X1_ } +procedure curve3_ctrl_impl.x1_; +begin + m_poly.xn_ptr(0 )^:=x; + +end; + +{ Y1_ } +procedure curve3_ctrl_impl.y1_; +begin + m_poly.yn_ptr(0 )^:=y; + +end; + +{ X2_ } +procedure curve3_ctrl_impl.x2_; +begin + m_poly.xn_ptr(1 )^:=x; + +end; + +{ Y2_ } +procedure curve3_ctrl_impl.y2_; +begin + m_poly.yn_ptr(1 )^:=y; + +end; + +{ X3_ } +procedure curve3_ctrl_impl.x3_; +begin + m_poly.xn_ptr(2 )^:=x; + +end; + +{ Y3_ } +procedure curve3_ctrl_impl.y3_; +begin + m_poly.yn_ptr(2 )^:=y; + +end; + +{ LINE_WIDTH_ } +procedure curve3_ctrl_impl.line_width_; +begin + m_stroke.width_(w ); + +end; + +{ _LINE_WIDTH } +function curve3_ctrl_impl._line_width; +begin + result:=m_stroke._width; + +end; + +{ POINT_RADIUS_ } +procedure curve3_ctrl_impl.point_radius_; +begin + m_poly.point_radius_(r ); + +end; + +{ _POINT_RADIUS } +function curve3_ctrl_impl._point_radius; +begin + result:=m_poly._point_radius; + +end; + +{ IN_RECT } +function curve3_ctrl_impl.in_rect; +begin + result:=false; + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function curve3_ctrl_impl.on_mouse_button_down; +begin + inverse_transform_xy(@x ,@y ); + + result:=m_poly.on_mouse_button_down(x ,y ); + +end; + +{ ON_MOUSE_BUTTON_UP } +function curve3_ctrl_impl.on_mouse_button_up; +begin + result:=m_poly.on_mouse_button_up(x ,y ); + +end; + +{ ON_MOUSE_MOVE } +function curve3_ctrl_impl.on_mouse_move; +begin + inverse_transform_xy(@x ,@y ); + + result:=m_poly.on_mouse_move(x ,y ,button_flag ); + +end; + +{ ON_ARROW_KEYS } +function curve3_ctrl_impl.on_arrow_keys; +begin + result:=m_poly.on_arrow_keys(left ,right ,down ,up ); + +end; + +{ NUM_PATHS } +function curve3_ctrl_impl.num_paths; +begin + result:=6; + +end; + +{ REWIND } +procedure curve3_ctrl_impl.rewind; +begin + m_idx:=path_id; + + case path_id of + 0 : // Control line + begin + m_curve.init3( + m_poly._xn(0 ) ,m_poly._yn(0 ) , + (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5, + (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5, + m_poly._xn(1 ) ,m_poly._yn(1 ) ); + + m_stroke.rewind(0 ); + + end; + + 1 : // Control line 2 + begin + m_curve.init3( + m_poly._xn(1 ) ,m_poly._yn(1 ) , + (m_poly._xn(1 ) + m_poly._xn(2 ) ) * 0.5, + (m_poly._yn(1 ) + m_poly._yn(2 ) ) * 0.5, + m_poly._xn(2 ) ,m_poly._yn(2 ) ); + + m_stroke.rewind(0 ); + + end; + + 2 : // Curve itself + begin + m_curve.init3( + m_poly._xn(0 ) ,m_poly._yn(0 ) , + m_poly._xn(1 ) ,m_poly._yn(1 ) , + m_poly._xn(2 ) ,m_poly._yn(2 ) ); + + m_stroke.rewind(0 ); + + end; + + 3 : // Point 1 + begin + m_ellipse.init (m_poly._xn(0 ) ,m_poly._yn(0 ) ,_point_radius ,_point_radius ,20 ); + m_ellipse.rewind(0 ); + + end; + + 4 : // Point 2 + begin + m_ellipse.init (m_poly._xn(1 ) ,m_poly._yn(1 ) ,_point_radius ,_point_radius ,20 ); + m_ellipse.rewind(0 ); + + end; + + 5 : // Point 3 + begin + m_ellipse.init (m_poly._xn(2 ) ,m_poly._yn(2 ) ,_point_radius ,_point_radius ,20 ); + m_ellipse.rewind(0 ); + + end; + + end; + +end; + +{ VERTEX } +function curve3_ctrl_impl.vertex; +var + cmd : unsigned; + +begin + cmd:=path_cmd_stop; + + case m_idx of + 0 ,1 ,2 : + cmd:=m_stroke.vertex(x ,y ); + + 3 ,4 ,5 ,6 : + cmd:=m_ellipse.vertex(x ,y ); + + end; + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ CONSTRUCT } +constructor curve3_ctrl.Construct; +begin + inherited Construct; + + m_color.ConstrDbl(0.0 ,0.0 ,0.0 ); + +end; + +{ LINE_COLOR_ } +procedure curve3_ctrl.line_color_; +begin + m_color:=c^; + +end; + +{ _COLOR } +function curve3_ctrl._color; +begin + result:=@m_color; + +end; + +END. + diff --git a/src/corelib/render/software/ctrl/agg_cbox_ctrl.pas b/src/corelib/render/software/ctrl/agg_cbox_ctrl.pas index f8245efa..545de382 100644 --- a/src/corelib/render/software/ctrl/agg_cbox_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_cbox_ctrl.pas @@ -1,430 +1,430 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 15.01.2006-Milano: Unit port establishment
-//
-{ agg_cbox_ctrl.pas }
-unit
- agg_cbox_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- SysUtils ,
- agg_basics ,
- agg_ctrl ,
- agg_conv_stroke ,
- agg_gsv_text ,
- agg_color ,
- agg_math_stroke ;
-
-{ TYPES DEFINITION }
-type
- cbox_ctrl_impl = object(ctrl )
- m_text_thickness ,
- m_text_height ,
- m_text_width : double;
-
- m_label : array[0..127 ] of char;
- m_status : boolean;
-
- m_vx ,
- m_vy : array[0..31 ] of double;
-
- m_text : gsv_text;
- m_text_poly : conv_stroke;
-
- m_idx ,
- m_vertex : unsigned;
-
- constructor Construct(x ,y : double; l : PChar; flip_y : boolean = false );
- destructor Destruct; virtual;
-
- procedure text_thickness_(t : double );
- procedure text_size_ (h : double; w : double = 0 );
-
- function _label : PChar;
- procedure label_(l : PChar );
-
- function _status : boolean;
- procedure status_(st : boolean );
-
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- // Vertex source interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- end;
-
- cbox_ctrl_ptr = ^cbox_ctrl;
- cbox_ctrl = object(cbox_ctrl_impl )
- m_text_color ,
- m_inactive_color ,
- m_active_color : aggclr;
-
- m_colors : array[0..2 ] of aggclr_ptr;
-
- constructor Construct(x ,y : double; l : PChar; flip_y : boolean = false );
-
- procedure text_color_ (c : aggclr_ptr );
- procedure inactive_color_(c : aggclr_ptr );
- procedure active_color_ (c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor cbox_ctrl_impl.Construct;
-begin
- inherited Construct(x ,y ,x + 9.0 * 1.5 ,y + 9.0 * 1.5 ,flip_y );
-
- m_text.Construct;
- m_text_poly.Construct(@m_text );
-
- m_text_thickness:=1.5;
- m_text_height :=9.0;
- m_text_width :=0.0;
-
- m_status:=false;
-
- label_(l );
-
-end;
-
-{ DESTRUCT }
-destructor cbox_ctrl_impl.Destruct;
-begin
- m_text_poly.Destruct;
- m_text.Destruct;
-
-end;
-
-{ TEXT_THICKNESS_ }
-procedure cbox_ctrl_impl.text_thickness_;
-begin
- m_text_thickness:=t;
-
-end;
-
-{ TEXT_SIZE_ }
-procedure cbox_ctrl_impl.text_size_;
-begin
- m_text_width :=w;
- m_text_height:=h;
-
-end;
-
-{ _LABEL }
-function cbox_ctrl_impl._label;
-begin
- result:=@m_label[0 ];
-
-end;
-
-{ LABEL_ }
-procedure cbox_ctrl_impl.label_;
-var
- len : unsigned;
-
-begin
- len:=StrLen(l );
-
- if len > 127 then
- len:=127;
-
- move(l^ ,m_label[0 ] ,len );
-
- m_label[len ]:=#0;
-
-end;
-
-{ _STATUS }
-function cbox_ctrl_impl._status;
-begin
- result:=m_status;
-
-end;
-
-{ STATUS_ }
-procedure cbox_ctrl_impl.status_;
-begin
- m_status:=st;
-
-end;
-
-{ IN_RECT }
-function cbox_ctrl_impl.in_rect;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=
- (x >= m_x1 ) and
- (y >= m_y1 ) and
- (x <= m_x2 ) and
- (y <= m_y2 );
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function cbox_ctrl_impl.on_mouse_button_down;
-begin
- inverse_transform_xy(@x ,@y );
-
- if (x >= m_x1 ) and
- (y >= m_y1 ) and
- (x <= m_x2 ) and
- (y <= m_y2 ) then
- begin
- m_status:=not m_status;
-
- result:=true;
-
- end
- else
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function cbox_ctrl_impl.on_mouse_button_up;
-begin
- result:=false;
-
-end;
-
-{ ON_MOUSE_MOVE }
-function cbox_ctrl_impl.on_mouse_move;
-begin
- result:=false;
-
-end;
-
-{ ON_ARROW_KEYS }
-function cbox_ctrl_impl.on_arrow_keys;
-begin
- result:=false;
-
-end;
-
-{ NUM_PATHS }
-function cbox_ctrl_impl.num_paths;
-begin
- result:=3;
-
-end;
-
-{ REWIND }
-procedure cbox_ctrl_impl.rewind;
-var
- d2 ,t : double;
-
-begin
- m_idx:=path_id;
-
- case path_id of
- 0 : // Border
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1;
- m_vy[0 ]:=m_y1;
- m_vx[1 ]:=m_x2;
- m_vy[1 ]:=m_y1;
- m_vx[2 ]:=m_x2;
- m_vy[2 ]:=m_y2;
- m_vx[3 ]:=m_x1;
- m_vy[3 ]:=m_y2;
- m_vx[4 ]:=m_x1 + m_text_thickness;
- m_vy[4 ]:=m_y1 + m_text_thickness;
- m_vx[5 ]:=m_x1 + m_text_thickness;
- m_vy[5 ]:=m_y2 - m_text_thickness;
- m_vx[6 ]:=m_x2 - m_text_thickness;
- m_vy[6 ]:=m_y2 - m_text_thickness;
- m_vx[7 ]:=m_x2 - m_text_thickness;
- m_vy[7 ]:=m_y1 + m_text_thickness;
-
- end;
-
- 1 : // Text
- begin
- m_text.text_ (@m_label[0 ] );
- m_text.start_point_(m_x1 + m_text_height * 2.0 ,m_y1 + m_text_height / 5.0 );
- m_text.size_ (m_text_height ,m_text_width );
-
- m_text_poly.width_ (m_text_thickness );
- m_text_poly.line_join_(round_join );
- m_text_poly.line_cap_ (round_cap );
-
- m_text_poly.rewind(0 );
-
- end;
-
- 2 : // Active item
- begin
- m_vertex:=0;
-
- d2:=(m_y2 - m_y1 ) / 2.0;
- t :=m_text_thickness * 1.5;
-
- m_vx[0 ]:=m_x1 + m_text_thickness;
- m_vy[0 ]:=m_y1 + m_text_thickness;
- m_vx[1 ]:=m_x1 + d2;
- m_vy[1 ]:=m_y1 + d2 - t;
- m_vx[2 ]:=m_x2 - m_text_thickness;
- m_vy[2 ]:=m_y1 + m_text_thickness;
- m_vx[3 ]:=m_x1 + d2 + t;
- m_vy[3 ]:=m_y1 + d2;
- m_vx[4 ]:=m_x2 - m_text_thickness;
- m_vy[4 ]:=m_y2 - m_text_thickness;
- m_vx[5 ]:=m_x1 + d2;
- m_vy[5 ]:=m_y1 + d2 + t;
- m_vx[6 ]:=m_x1 + m_text_thickness;
- m_vy[6 ]:=m_y2 - m_text_thickness;
- m_vx[7 ]:=m_x1 + d2 - t;
- m_vy[7 ]:=m_y1 + d2;
-
- end;
-
- end;
-
-end;
-
-{ VERTEX }
-function cbox_ctrl_impl.vertex;
-var
- cmd : unsigned;
-
-begin
- cmd:=path_cmd_line_to;
-
- case m_idx of
- 0 :
- begin
- if (m_vertex = 0 ) or
- (m_vertex = 4 ) then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 8then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 1 :
- cmd:=m_text_poly.vertex(x ,y );
-
- 2 :
- if m_status then
- begin
- if m_vertex = 0 then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 8 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end
- else
- cmd:=path_cmd_stop;
-
- else
- cmd:=path_cmd_stop;
-
- end;
-
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ CONSTRUCT }
-constructor cbox_ctrl.Construct;
-begin
- inherited Construct(x ,y ,l ,flip_y );
-
- m_text_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_inactive_color.ConstrDbl(0.0 ,0.0 ,0.0 );
- m_active_color.ConstrDbl (0.4 ,0.0 ,0.0 );
-
- m_colors[0 ]:=@m_inactive_color;
- m_colors[1 ]:=@m_text_color;
- m_colors[2 ]:=@m_active_color;
-
-end;
-
-{ TEXT_COLOR_ }
-procedure cbox_ctrl.text_color_;
-begin
- m_text_color:=c^;
-
-end;
-
-{ INACTIVE_COLOR_ }
-procedure cbox_ctrl.inactive_color_;
-begin
- m_inactive_color:=c^;
-
-end;
-
-{ ACTIVE_COLOR_ }
-procedure cbox_ctrl.active_color_;
-begin
- m_active_color:=c^;
-
-end;
-
-{ _COLOR }
-function cbox_ctrl._color;
-begin
- result:=m_colors[i ];
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 15.01.2006-Milano: Unit port establishment +// +{ agg_cbox_ctrl.pas } +unit + agg_cbox_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + SysUtils , + agg_basics , + agg_ctrl , + agg_conv_stroke , + agg_gsv_text , + agg_color , + agg_math_stroke ; + +{ TYPES DEFINITION } +type + cbox_ctrl_impl = object(ctrl ) + m_text_thickness , + m_text_height , + m_text_width : double; + + m_label : array[0..127 ] of char; + m_status : boolean; + + m_vx , + m_vy : array[0..31 ] of double; + + m_text : gsv_text; + m_text_poly : conv_stroke; + + m_idx , + m_vertex : unsigned; + + constructor Construct(x ,y : double; l : PChar; flip_y : boolean = false ); + destructor Destruct; virtual; + + procedure text_thickness_(t : double ); + procedure text_size_ (h : double; w : double = 0 ); + + function _label : PChar; + procedure label_(l : PChar ); + + function _status : boolean; + procedure status_(st : boolean ); + + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Vertex source interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + end; + + cbox_ctrl_ptr = ^cbox_ctrl; + cbox_ctrl = object(cbox_ctrl_impl ) + m_text_color , + m_inactive_color , + m_active_color : aggclr; + + m_colors : array[0..2 ] of aggclr_ptr; + + constructor Construct(x ,y : double; l : PChar; flip_y : boolean = false ); + + procedure text_color_ (c : aggclr_ptr ); + procedure inactive_color_(c : aggclr_ptr ); + procedure active_color_ (c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor cbox_ctrl_impl.Construct; +begin + inherited Construct(x ,y ,x + 9.0 * 1.5 ,y + 9.0 * 1.5 ,flip_y ); + + m_text.Construct; + m_text_poly.Construct(@m_text ); + + m_text_thickness:=1.5; + m_text_height :=9.0; + m_text_width :=0.0; + + m_status:=false; + + label_(l ); + +end; + +{ DESTRUCT } +destructor cbox_ctrl_impl.Destruct; +begin + m_text_poly.Destruct; + m_text.Destruct; + +end; + +{ TEXT_THICKNESS_ } +procedure cbox_ctrl_impl.text_thickness_; +begin + m_text_thickness:=t; + +end; + +{ TEXT_SIZE_ } +procedure cbox_ctrl_impl.text_size_; +begin + m_text_width :=w; + m_text_height:=h; + +end; + +{ _LABEL } +function cbox_ctrl_impl._label; +begin + result:=@m_label[0 ]; + +end; + +{ LABEL_ } +procedure cbox_ctrl_impl.label_; +var + len : unsigned; + +begin + len:=StrLen(l ); + + if len > 127 then + len:=127; + + move(l^ ,m_label[0 ] ,len ); + + m_label[len ]:=#0; + +end; + +{ _STATUS } +function cbox_ctrl_impl._status; +begin + result:=m_status; + +end; + +{ STATUS_ } +procedure cbox_ctrl_impl.status_; +begin + m_status:=st; + +end; + +{ IN_RECT } +function cbox_ctrl_impl.in_rect; +begin + inverse_transform_xy(@x ,@y ); + + result:= + (x >= m_x1 ) and + (y >= m_y1 ) and + (x <= m_x2 ) and + (y <= m_y2 ); + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function cbox_ctrl_impl.on_mouse_button_down; +begin + inverse_transform_xy(@x ,@y ); + + if (x >= m_x1 ) and + (y >= m_y1 ) and + (x <= m_x2 ) and + (y <= m_y2 ) then + begin + m_status:=not m_status; + + result:=true; + + end + else + result:=false; + +end; + +{ ON_MOUSE_BUTTON_UP } +function cbox_ctrl_impl.on_mouse_button_up; +begin + result:=false; + +end; + +{ ON_MOUSE_MOVE } +function cbox_ctrl_impl.on_mouse_move; +begin + result:=false; + +end; + +{ ON_ARROW_KEYS } +function cbox_ctrl_impl.on_arrow_keys; +begin + result:=false; + +end; + +{ NUM_PATHS } +function cbox_ctrl_impl.num_paths; +begin + result:=3; + +end; + +{ REWIND } +procedure cbox_ctrl_impl.rewind; +var + d2 ,t : double; + +begin + m_idx:=path_id; + + case path_id of + 0 : // Border + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1; + m_vy[0 ]:=m_y1; + m_vx[1 ]:=m_x2; + m_vy[1 ]:=m_y1; + m_vx[2 ]:=m_x2; + m_vy[2 ]:=m_y2; + m_vx[3 ]:=m_x1; + m_vy[3 ]:=m_y2; + m_vx[4 ]:=m_x1 + m_text_thickness; + m_vy[4 ]:=m_y1 + m_text_thickness; + m_vx[5 ]:=m_x1 + m_text_thickness; + m_vy[5 ]:=m_y2 - m_text_thickness; + m_vx[6 ]:=m_x2 - m_text_thickness; + m_vy[6 ]:=m_y2 - m_text_thickness; + m_vx[7 ]:=m_x2 - m_text_thickness; + m_vy[7 ]:=m_y1 + m_text_thickness; + + end; + + 1 : // Text + begin + m_text.text_ (@m_label[0 ] ); + m_text.start_point_(m_x1 + m_text_height * 2.0 ,m_y1 + m_text_height / 5.0 ); + m_text.size_ (m_text_height ,m_text_width ); + + m_text_poly.width_ (m_text_thickness ); + m_text_poly.line_join_(round_join ); + m_text_poly.line_cap_ (round_cap ); + + m_text_poly.rewind(0 ); + + end; + + 2 : // Active item + begin + m_vertex:=0; + + d2:=(m_y2 - m_y1 ) / 2.0; + t :=m_text_thickness * 1.5; + + m_vx[0 ]:=m_x1 + m_text_thickness; + m_vy[0 ]:=m_y1 + m_text_thickness; + m_vx[1 ]:=m_x1 + d2; + m_vy[1 ]:=m_y1 + d2 - t; + m_vx[2 ]:=m_x2 - m_text_thickness; + m_vy[2 ]:=m_y1 + m_text_thickness; + m_vx[3 ]:=m_x1 + d2 + t; + m_vy[3 ]:=m_y1 + d2; + m_vx[4 ]:=m_x2 - m_text_thickness; + m_vy[4 ]:=m_y2 - m_text_thickness; + m_vx[5 ]:=m_x1 + d2; + m_vy[5 ]:=m_y1 + d2 + t; + m_vx[6 ]:=m_x1 + m_text_thickness; + m_vy[6 ]:=m_y2 - m_text_thickness; + m_vx[7 ]:=m_x1 + d2 - t; + m_vy[7 ]:=m_y1 + d2; + + end; + + end; + +end; + +{ VERTEX } +function cbox_ctrl_impl.vertex; +var + cmd : unsigned; + +begin + cmd:=path_cmd_line_to; + + case m_idx of + 0 : + begin + if (m_vertex = 0 ) or + (m_vertex = 4 ) then + cmd:=path_cmd_move_to; + + if m_vertex >= 8then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 1 : + cmd:=m_text_poly.vertex(x ,y ); + + 2 : + if m_status then + begin + if m_vertex = 0 then + cmd:=path_cmd_move_to; + + if m_vertex >= 8 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end + else + cmd:=path_cmd_stop; + + else + cmd:=path_cmd_stop; + + end; + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ CONSTRUCT } +constructor cbox_ctrl.Construct; +begin + inherited Construct(x ,y ,l ,flip_y ); + + m_text_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_inactive_color.ConstrDbl(0.0 ,0.0 ,0.0 ); + m_active_color.ConstrDbl (0.4 ,0.0 ,0.0 ); + + m_colors[0 ]:=@m_inactive_color; + m_colors[1 ]:=@m_text_color; + m_colors[2 ]:=@m_active_color; + +end; + +{ TEXT_COLOR_ } +procedure cbox_ctrl.text_color_; +begin + m_text_color:=c^; + +end; + +{ INACTIVE_COLOR_ } +procedure cbox_ctrl.inactive_color_; +begin + m_inactive_color:=c^; + +end; + +{ ACTIVE_COLOR_ } +procedure cbox_ctrl.active_color_; +begin + m_active_color:=c^; + +end; + +{ _COLOR } +function cbox_ctrl._color; +begin + result:=m_colors[i ]; + +end; + +END. + diff --git a/src/corelib/render/software/ctrl/agg_ctrl.pas b/src/corelib/render/software/ctrl/agg_ctrl.pas index 0c8d198e..81372532 100644 --- a/src/corelib/render/software/ctrl/agg_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_ctrl.pas @@ -1,223 +1,223 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-//----------------------------------------------------------------------------
-//
-// Function render_ctrl
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 13.12.2005-Milano: Unit port establishment
-//
-{ agg_ctrl.pas }
-unit
- agg_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- agg_basics ,
- agg_trans_affine ,
- agg_rasterizer_scanline_aa ,
- agg_scanline ,
- agg_renderer_scanline ,
- agg_render_scanlines ,
- agg_vertex_source ,
- agg_color ;
-
-{ TYPES DEFINITION }
-type
- ctrl_ptr = ^ctrl;
- ctrl = object(vertex_source )
- m_x1 ,
- m_y1 ,
- m_x2 ,
- m_y2 : double;
-
- m_flip_y : boolean;
-
- m_mtx : trans_affine_ptr;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean );
- destructor Destruct; virtual;
-
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- procedure transform(mtx : trans_affine_ptr );
- procedure no_transform;
-
- procedure transform_xy(x ,y : double_ptr );
-
- procedure inverse_transform_xy(x ,y : double_ptr );
-
- function scale : double;
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
- procedure render_ctrl(ras : rasterizer_scanline_ptr; sl : scanline_ptr; r : renderer_scanline_ptr; c : ctrl_ptr );
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor ctrl.Construct;
-begin
- inherited Construct;
-
- m_x1:=x1;
- m_y1:=y1;
- m_x2:=x2;
- m_y2:=y2;
-
- m_flip_y:=flip_y;
-
- m_mtx:=NIL;
-
-end;
-
-{ DESTRUCT }
-destructor ctrl.Destruct;
-begin
- inherited Destruct;
-
-end;
-
-{ IN_RECT }
-function ctrl.in_rect;
-begin
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function ctrl.on_mouse_button_down;
-begin
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function ctrl.on_mouse_button_up;
-begin
- result:=false;
-
-end;
-
-{ ON_MOUSE_MOVE }
-function ctrl.on_mouse_move;
-begin
- result:=false;
-
-end;
-
-{ ON_ARROW_KEYS }
-function ctrl.on_arrow_keys;
-begin
- result:=false;
-
-end;
-
-{ TRANSFORM }
-procedure ctrl.transform;
-begin
- m_mtx:=mtx;
-
-end;
-
-{ NO_TRANSFORM }
-procedure ctrl.no_transform;
-begin
- m_mtx:=NIL;
-
-end;
-
-{ TRANSFORM_XY }
-procedure ctrl.transform_xy;
-begin
- if m_flip_y then
- y^:=m_y1 + m_y2 - y^;
-
- if m_mtx <> NIL then
- m_mtx.transform(m_mtx ,x ,y );
-
-end;
-
-{ INVERSE_TRANSFORM_XY }
-procedure ctrl.inverse_transform_xy;
-begin
- if m_mtx <> NIL then
- m_mtx.inverse_transform(m_mtx ,x ,y );
-
- if m_flip_y then
- y^:=m_y1 + m_y2 - y^;
-
-end;
-
-{ SCALE }
-function ctrl.scale;
-begin
- if m_mtx <> NIL then
- result:=m_mtx.scale
- else
- result:=1.0;
-
-end;
-
-{ _COLOR }
-function ctrl._color;
-begin
- result:=NIL;
-
-end;
-
-{ RENDER_CTRL }
-procedure render_ctrl;
-var
- i : unsigned;
-
-begin
- if c.num_paths > 0 then
- for i:=0 to c.num_paths - 1 do
- begin
- ras.reset;
- ras.add_path(c ,i );
-
- r.color_(c._color(i ) );
-
- render_scanlines(ras ,sl ,r );
-
- end;
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +//---------------------------------------------------------------------------- +// +// Function render_ctrl +// +// [Pascal Port History] ----------------------------------------------------- +// +// 13.12.2005-Milano: Unit port establishment +// +{ agg_ctrl.pas } +unit + agg_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + agg_basics , + agg_trans_affine , + agg_rasterizer_scanline_aa , + agg_scanline , + agg_renderer_scanline , + agg_render_scanlines , + agg_vertex_source , + agg_color ; + +{ TYPES DEFINITION } +type + ctrl_ptr = ^ctrl; + ctrl = object(vertex_source ) + m_x1 , + m_y1 , + m_x2 , + m_y2 : double; + + m_flip_y : boolean; + + m_mtx : trans_affine_ptr; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean ); + destructor Destruct; virtual; + + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + procedure transform(mtx : trans_affine_ptr ); + procedure no_transform; + + procedure transform_xy(x ,y : double_ptr ); + + procedure inverse_transform_xy(x ,y : double_ptr ); + + function scale : double; + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + procedure render_ctrl(ras : rasterizer_scanline_ptr; sl : scanline_ptr; r : renderer_scanline_ptr; c : ctrl_ptr ); + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor ctrl.Construct; +begin + inherited Construct; + + m_x1:=x1; + m_y1:=y1; + m_x2:=x2; + m_y2:=y2; + + m_flip_y:=flip_y; + + m_mtx:=NIL; + +end; + +{ DESTRUCT } +destructor ctrl.Destruct; +begin + inherited Destruct; + +end; + +{ IN_RECT } +function ctrl.in_rect; +begin + result:=false; + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function ctrl.on_mouse_button_down; +begin + result:=false; + +end; + +{ ON_MOUSE_BUTTON_UP } +function ctrl.on_mouse_button_up; +begin + result:=false; + +end; + +{ ON_MOUSE_MOVE } +function ctrl.on_mouse_move; +begin + result:=false; + +end; + +{ ON_ARROW_KEYS } +function ctrl.on_arrow_keys; +begin + result:=false; + +end; + +{ TRANSFORM } +procedure ctrl.transform; +begin + m_mtx:=mtx; + +end; + +{ NO_TRANSFORM } +procedure ctrl.no_transform; +begin + m_mtx:=NIL; + +end; + +{ TRANSFORM_XY } +procedure ctrl.transform_xy; +begin + if m_flip_y then + y^:=m_y1 + m_y2 - y^; + + if m_mtx <> NIL then + m_mtx.transform(m_mtx ,x ,y ); + +end; + +{ INVERSE_TRANSFORM_XY } +procedure ctrl.inverse_transform_xy; +begin + if m_mtx <> NIL then + m_mtx.inverse_transform(m_mtx ,x ,y ); + + if m_flip_y then + y^:=m_y1 + m_y2 - y^; + +end; + +{ SCALE } +function ctrl.scale; +begin + if m_mtx <> NIL then + result:=m_mtx.scale + else + result:=1.0; + +end; + +{ _COLOR } +function ctrl._color; +begin + result:=NIL; + +end; + +{ RENDER_CTRL } +procedure render_ctrl; +var + i : unsigned; + +begin + if c.num_paths > 0 then + for i:=0 to c.num_paths - 1 do + begin + ras.reset; + ras.add_path(c ,i ); + + r.color_(c._color(i ) ); + + render_scanlines(ras ,sl ,r ); + + end; + +end; + +END. + diff --git a/src/corelib/render/software/ctrl/agg_gamma_ctrl.pas b/src/corelib/render/software/ctrl/agg_gamma_ctrl.pas index da79fdcf..1fc6e698 100644 --- a/src/corelib/render/software/ctrl/agg_gamma_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_gamma_ctrl.pas @@ -1,881 +1,881 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 30.01.2006-Milano: Unit port establishment
-//
-{ agg_gamma_ctrl.pas }
-unit
- agg_gamma_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- SysUtils ,
- agg_basics ,
- agg_gamma_spline ,
- agg_ellipse ,
- agg_conv_stroke ,
- agg_gsv_text ,
- agg_trans_affine ,
- agg_color ,
- agg_ctrl ,
- agg_math ,
- agg_math_stroke ;
-
-{ TYPES DEFINITION }
-type
- gamma_ctrl_impl = object(ctrl )
- m_gamma_spline : gamma_spline;
-
- m_border_width ,
- m_border_extra ,
- m_curve_width ,
- m_grid_width ,
- m_text_thickness ,
- m_point_size ,
- m_text_height ,
- m_text_width ,
-
- m_xc1 ,
- m_yc1 ,
- m_xc2 ,
- m_yc2 ,
- m_xs1 ,
- m_ys1 ,
- m_xs2 ,
- m_ys2 ,
- m_xt1 ,
- m_yt1 ,
- m_xt2 ,
- m_yt2 : double;
-
- m_curve_poly : conv_stroke;
- m_ellipse : ellipse;
- m_text : gsv_text;
- m_text_poly : conv_stroke;
-
- m_idx ,
- m_vertex : unsigned;
-
- m_vx ,
- m_vy : array[0..31 ] of double;
-
- m_xp1 ,
- m_yp1 ,
- m_xp2 ,
- m_yp2 : double;
-
- m_p1_active : boolean;
- m_mouse_point : unsigned;
-
- m_pdx ,
- m_pdy : double;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false );
- destructor Destruct; virtual;
-
- // Set other parameters
- procedure border_width_ (t : double; extra : double = 0.0 );
- procedure curve_width_ (t : double );
- procedure grid_width_ (t : double );
- procedure text_thickness_(t : double );
- procedure text_size_ (h : double; w : double = 0.0 );
- procedure point_size_ (s : double );
-
- // Event handlers. Just call them if the respective events
- // in your system occure. The functions return true if redrawing
- // is required.
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- procedure change_active_point;
-
- // A copy of gamma_spline interface
- procedure values(kx1 ,ky1 ,kx2 ,ky2 : double ); overload;
- procedure values(kx1 ,ky1 ,kx2 ,ky2 : double_ptr ); overload;
-
- function gamma : char_ptr;
- function _y(x : double ) : double;
-
- function func_operator_gamma(x : double ) : double; virtual;
-
- // Vertex soutce interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- // Private
- procedure calc_spline_box;
- procedure calc_points;
- procedure calc_values;
-
- end;
-
- gamma_ctrl = object(gamma_ctrl_impl )
- m_background_color ,
- m_border_color ,
- m_curve_color ,
- m_grid_color ,
- m_inactive_pnt_color ,
- m_active_pnt_color ,
- m_text_color : aggclr;
-
- m_colors : array[0..6 ] of aggclr_ptr;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false );
-
- procedure background_color_ (c : aggclr_ptr );
- procedure border_color_ (c : aggclr_ptr );
- procedure curve_color_ (c : aggclr_ptr );
- procedure grid_color_ (c : aggclr_ptr );
- procedure inactive_pnt_color_(c : aggclr_ptr );
- procedure active_pnt_color_ (c : aggclr_ptr );
- procedure text_color_ (c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor gamma_ctrl_impl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y );
-
- m_border_width :=2.0;
- m_border_extra :=0.0;
- m_curve_width :=2.0;
- m_grid_width :=0.2;
- m_text_thickness:=1.5;
- m_point_size :=5.0;
- m_text_height :=9.0;
- m_text_width :=0.0;
-
- m_xc1:=x1;
- m_yc1:=y1;
- m_xc2:=x2;
- m_yc2:=y2 - m_text_height * 2.0;
- m_xt1:=x1;
- m_yt1:=y2 - m_text_height * 2.0;
- m_xt2:=x2;
- m_yt2:=y2;
-
- m_gamma_spline.Construct;
- m_ellipse.Construct;
- m_curve_poly.Construct(@m_gamma_spline );
- m_text.Construct;
- m_text_poly.Construct (@m_text );
-
- m_idx :=0;
- m_vertex:=0;
-
- m_p1_active :=true;
- m_mouse_point:=0;
-
- m_pdx:=0.0;
- m_pdy:=0.0;
-
- calc_spline_box;
-
-end;
-
-{ DESTRUCT }
-destructor gamma_ctrl_impl.Destruct;
-begin
- m_gamma_spline.Destruct;
- m_curve_poly.Destruct;
- m_text.Destruct;
- m_text_poly.Destruct;
-
-end;
-
-{ BORDER_WIDTH_ }
-procedure gamma_ctrl_impl.border_width_;
-begin
- m_border_width:=t;
- m_border_extra:=extra;
-
- calc_spline_box;
-
-end;
-
-{ CURVE_WIDTH_ }
-procedure gamma_ctrl_impl.curve_width_;
-begin
- m_curve_width:=t;
-
-end;
-
-{ GRID_WIDTH_ }
-procedure gamma_ctrl_impl.grid_width_;
-begin
- m_grid_width:=t;
-
-end;
-
-{ TEXT_THICKNESS_ }
-procedure gamma_ctrl_impl.text_thickness_;
-begin
- m_text_thickness:=t;
-
-end;
-
-{ TEXT_SIZE_ }
-procedure gamma_ctrl_impl.text_size_;
-begin
- m_text_width :=w;
- m_text_height:=h;
-
- m_yc2:=m_y2 - m_text_height * 2.0;
- m_yt1:=m_y2 - m_text_height * 2.0;
-
- calc_spline_box;
-
-end;
-
-{ POINT_SIZE_ }
-procedure gamma_ctrl_impl.point_size_;
-begin
- m_point_size:=s;
-
-end;
-
-{ IN_RECT }
-function gamma_ctrl_impl.in_rect;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=
- (x >= m_x1 ) and
- (x <= m_x2 ) and
- (y >= m_y1 ) and
- (y <= m_y2 );
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function gamma_ctrl_impl.on_mouse_button_down;
-begin
- inverse_transform_xy(@x ,@y );
- calc_points;
-
- if calc_distance(x ,y ,m_xp1 ,m_yp1 ) <= m_point_size + 1 then
- begin
- m_mouse_point:=1;
-
- m_pdx:=m_xp1 - x;
- m_pdy:=m_yp1 - y;
-
- m_p1_active:=true;
-
- result:=true;
-
- exit;
-
- end;
-
- if calc_distance(x ,y ,m_xp2 ,m_yp2 ) <= m_point_size + 1 then
- begin
- m_mouse_point:=2;
-
- m_pdx:=m_xp2 - x;
- m_pdy:=m_yp2 - y;
-
- m_p1_active:=false;
-
- result:=true;
-
- exit;
-
- end;
-
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function gamma_ctrl_impl.on_mouse_button_up;
-begin
- if m_mouse_point <> 0 then
- begin
- m_mouse_point:=0;
-
- result:=true;
-
- end
- else
- result:=false;
-
-end;
-
-{ ON_MOUSE_MOVE }
-function gamma_ctrl_impl.on_mouse_move;
-begin
- inverse_transform_xy(@x ,@y );
-
- if not button_flag then
- result:=on_mouse_button_up(x ,y )
- else
- begin
- if m_mouse_point = 1 then
- begin
- m_xp1:=x + m_pdx;
- m_yp1:=y + m_pdy;
-
- calc_values;
-
- result:=true;
-
- exit;
-
- end;
-
- if m_mouse_point = 2 then
- begin
- m_xp2:=x + m_pdx;
- m_yp2:=y + m_pdy;
-
- calc_values;
-
- result:=true;
-
- exit;
-
- end;
-
- result:=false;
-
- end;
-
-end;
-
-{ ON_ARROW_KEYS }
-function gamma_ctrl_impl.on_arrow_keys;
-var
- kx1 ,ky1 ,kx2 ,ky2 : double;
-
- ret : boolean;
-
-begin
- ret:=false;
-
- m_gamma_spline.values(@kx1 ,@ky1 ,@kx2 ,@ky2 );
-
- if m_p1_active then
- begin
- if left then
- begin
- kx1:=kx1 - 0.005;
- ret:=true;
-
- end;
-
- if right then
- begin
- kx1:=kx1 + 0.005;
- ret:=true;
-
- end;
-
- if down then
- begin
- ky1:=ky1 - 0.005;
- ret:=true;
-
- end;
-
- if up then
- begin
- ky1:=ky1 + 0.005;
- ret:=true;
-
- end;
-
- end
- else
- begin
- if left then
- begin
- kx2:=kx2 + 0.005;
- ret:=true;
-
- end;
-
- if right then
- begin
- kx2:=kx2 - 0.005;
- ret:=true;
-
- end;
-
- if down then
- begin
- ky2:=ky2 + 0.005;
- ret:=true;
-
- end;
-
- if up then
- begin
- ky2:=ky2 - 0.005;
- ret:= true;
-
- end;
-
- end;
-
- if ret then
- m_gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 );
-
- result:=ret;
-
-end;
-
-{ CHANGE_ACTIVE_POINT }
-procedure gamma_ctrl_impl.change_active_point;
-begin
- if m_p1_active then
- m_p1_active:=false
- else
- m_p1_active:=true;
-
-end;
-
-{ VALUES }
-procedure gamma_ctrl_impl.values(kx1 ,ky1 ,kx2 ,ky2 : double );
-begin
- m_gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 );
-
-end;
-
-{ VALUES }
-procedure gamma_ctrl_impl.values(kx1 ,ky1 ,kx2 ,ky2 : double_ptr );
-begin
- m_gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 );
-
-end;
-
-{ GAMMA }
-function gamma_ctrl_impl.gamma;
-begin
- result:=m_gamma_spline.gamma;
-
-end;
-
-{ _Y }
-function gamma_ctrl_impl._y;
-begin
- result:=m_gamma_spline._y(x );
-
-end;
-
-{ FUNC_OPERATOR_GAMMA }
-function gamma_ctrl_impl.func_operator_gamma;
-begin
- result:=m_gamma_spline._y(x );
-
-end;
-
-{ NUM_PATHS }
-function gamma_ctrl_impl.num_paths;
-begin
- result:=7;
-
-end;
-
-{ REWIND }
-procedure gamma_ctrl_impl.rewind;
-var
- kx1 ,ky1 ,kx2 ,ky2 : double;
-
- tbuf : array[0..31 ] of char;
-
-begin
- m_idx:=path_id;
-
- case path_id of
- 0 : // Background
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1 - m_border_extra;
- m_vy[0 ]:=m_y1 - m_border_extra;
- m_vx[1 ]:=m_x2 + m_border_extra;
- m_vy[1 ]:=m_y1 - m_border_extra;
- m_vx[2 ]:=m_x2 + m_border_extra;
- m_vy[2 ]:=m_y2 + m_border_extra;
- m_vx[3 ]:=m_x1 - m_border_extra;
- m_vy[3 ]:=m_y2 + m_border_extra;
-
- end;
-
- 1 : // Border
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1;
- m_vy[0 ]:=m_y1;
- m_vx[1 ]:=m_x2;
- m_vy[1 ]:=m_y1;
- m_vx[2 ]:=m_x2;
- m_vy[2 ]:=m_y2;
- m_vx[3 ]:=m_x1;
- m_vy[3 ]:=m_y2;
- m_vx[4 ]:=m_x1 + m_border_width;
- m_vy[4 ]:=m_y1 + m_border_width;
- m_vx[5 ]:=m_x1 + m_border_width;
- m_vy[5 ]:=m_y2 - m_border_width;
- m_vx[6 ]:=m_x2 - m_border_width;
- m_vy[6 ]:=m_y2 - m_border_width;
- m_vx[7 ]:=m_x2 - m_border_width;
- m_vy[7 ]:=m_y1 + m_border_width;
- m_vx[8 ]:=m_xc1 + m_border_width;
- m_vy[8 ]:=m_yc2 - m_border_width * 0.5;
- m_vx[9 ]:=m_xc2 - m_border_width;
- m_vy[9 ]:=m_yc2 - m_border_width * 0.5;
- m_vx[10 ]:=m_xc2 - m_border_width;
- m_vy[10 ]:=m_yc2 + m_border_width * 0.5;
- m_vx[11 ]:=m_xc1 + m_border_width;
- m_vy[11 ]:=m_yc2 + m_border_width * 0.5;
-
- end;
-
- 2 : // Curve
- begin
- m_gamma_spline.box(m_xs1 ,m_ys1 ,m_xs2 ,m_ys2 );
-
- m_curve_poly.width_(m_curve_width );
- m_curve_poly.rewind(0 );
-
- end;
-
- 3 : // Grid
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_xs1;
- m_vy[0 ]:=(m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5;
- m_vx[1 ]:=m_xs2;
- m_vy[1 ]:=(m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5;
- m_vx[2 ]:=m_xs2;
- m_vy[2 ]:=(m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5;
- m_vx[3 ]:=m_xs1;
- m_vy[3 ]:=(m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5;
- m_vx[4 ]:=(m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5;
- m_vy[4 ]:=m_ys1;
- m_vx[5 ]:=(m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5;
- m_vy[5 ]:=m_ys2;
- m_vx[6 ]:=(m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5;
- m_vy[6 ]:=m_ys2;
- m_vx[7 ]:=(m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5;
- m_vy[7 ]:=m_ys1;
-
- calc_points;
-
- m_vx[8 ]:=m_xs1;
- m_vy[8 ]:=m_yp1 - m_grid_width * 0.5;
- m_vx[9 ]:=m_xp1 - m_grid_width * 0.5;
- m_vy[9 ]:=m_yp1 - m_grid_width * 0.5;
- m_vx[10 ]:=m_xp1 - m_grid_width * 0.5;
- m_vy[10 ]:=m_ys1;
- m_vx[11 ]:=m_xp1 + m_grid_width * 0.5;
- m_vy[11 ]:=m_ys1;
- m_vx[12 ]:=m_xp1 + m_grid_width * 0.5;
- m_vy[12 ]:=m_yp1 + m_grid_width * 0.5;
- m_vx[13 ]:=m_xs1;
- m_vy[13 ]:=m_yp1 + m_grid_width * 0.5;
- m_vx[14 ]:=m_xs2;
- m_vy[14 ]:=m_yp2 + m_grid_width * 0.5;
- m_vx[15 ]:=m_xp2 + m_grid_width * 0.5;
- m_vy[15 ]:=m_yp2 + m_grid_width * 0.5;
- m_vx[16 ]:=m_xp2 + m_grid_width * 0.5;
- m_vy[16 ]:=m_ys2;
- m_vx[17 ]:=m_xp2 - m_grid_width * 0.5;
- m_vy[17 ]:=m_ys2;
- m_vx[18 ]:=m_xp2 - m_grid_width * 0.5;
- m_vy[18 ]:=m_yp2 - m_grid_width * 0.5;
- m_vx[19 ]:=m_xs2;
- m_vy[19 ]:=m_yp2 - m_grid_width * 0.5;
-
- end;
-
- 4 : // Point1
- begin
- calc_points;
-
- if m_p1_active then
- m_ellipse.init(m_xp2 ,m_yp2 ,m_point_size ,m_point_size ,32 )
- else
- m_ellipse.init(m_xp1 ,m_yp1 ,m_point_size ,m_point_size ,32 );
-
- end;
-
- 5 : // Point2
- begin
- calc_points;
-
- if m_p1_active then
- m_ellipse.init(m_xp1 ,m_yp1 ,m_point_size ,m_point_size ,32 )
- else
- m_ellipse.init(m_xp2 ,m_yp2 ,m_point_size ,m_point_size ,32 );
-
- end;
-
- 6 : // Text
- begin
- m_gamma_spline.values(@kx1 ,@ky1 ,@kx2 ,@ky2 );
-
- sprintf(@tbuf[0] , '%.3f '#0 ,kx1 );
- sprintf(@tbuf[StrLen(@tbuf[0 ] ) ] ,'%.3f '#0 ,ky1 );
- sprintf(@tbuf[StrLen(@tbuf[0 ] ) ] ,'%.3f '#0 ,kx2 );
- sprintf(@tbuf[StrLen(@tbuf[0 ] ) ] ,'%.3f'#0 ,ky2 );
-
- m_text.text_(@tbuf[0 ] );
- m_text.size_(m_text_height ,m_text_width );
-
- m_text.start_point_(m_xt1 + m_border_width * 2.0 ,(m_yt1 + m_yt2 ) * 0.5 - m_text_height * 0.5 );
- m_text_poly.width_(m_text_thickness );
-
- m_text_poly.line_join_(round_join );
- m_text_poly.line_cap_ (round_cap );
-
- m_text_poly.rewind(0);
-
- end;
-
- end;
-
-end;
-
-{ VERTEX }
-function gamma_ctrl_impl.vertex;
-var
- cmd : unsigned;
-
-begin
- cmd:=path_cmd_line_to;
-
- case m_idx of
- 0 :
- begin
- if m_vertex = 0 then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 4 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 1 :
- begin
- if (m_vertex = 0 ) or
- (m_vertex = 4 ) or
- (m_vertex = 8 ) then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 12 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 2 :
- cmd:=m_curve_poly.vertex(x ,y );
-
- 3 :
- begin
- if (m_vertex = 0 ) or
- (m_vertex = 4 ) or
- (m_vertex = 8 ) or
- (m_vertex = 14 ) then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 20 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 4 ,5 :
- cmd:=m_ellipse.vertex(x ,y );
-
- 6 :
- cmd:=m_text_poly.vertex(x ,y );
-
- else
- cmd:=path_cmd_stop;
-
- end;
-
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ CALC_SPLINE_BOX }
-procedure gamma_ctrl_impl.calc_spline_box;
-begin
- m_xs1:=m_xc1 + m_border_width;
- m_ys1:=m_yc1 + m_border_width;
- m_xs2:=m_xc2 - m_border_width;
- m_ys2:=m_yc2 - m_border_width * 0.5;
-
-end;
-
-{ CALC_POINTS }
-procedure gamma_ctrl_impl.calc_points;
-var
- kx1 ,ky1 ,kx2 ,ky2 : double;
-
-begin
- m_gamma_spline.values(@kx1 ,@ky1 ,@kx2 ,@ky2 );
-
- m_xp1:=m_xs1 + (m_xs2 - m_xs1 ) * kx1 * 0.25;
- m_yp1:=m_ys1 + (m_ys2 - m_ys1 ) * ky1 * 0.25;
- m_xp2:=m_xs2 - (m_xs2 - m_xs1 ) * kx2 * 0.25;
- m_yp2:=m_ys2 - (m_ys2 - m_ys1 ) * ky2 * 0.25;
-
-end;
-
-{ CALC_VALUES }
-procedure gamma_ctrl_impl.calc_values;
-var
- kx1 ,ky1 ,kx2 ,ky2 : double;
-
-begin
- kx1:=(m_xp1 - m_xs1 ) * 4.0 / (m_xs2 - m_xs1 );
- ky1:=(m_yp1 - m_ys1 ) * 4.0 / (m_ys2 - m_ys1 );
- kx2:=(m_xs2 - m_xp2 ) * 4.0 / (m_xs2 - m_xs1 );
- ky2:=(m_ys2 - m_yp2 ) * 4.0 / (m_ys2 - m_ys1 );
-
- m_gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 );
-
-end;
-
-{ CONSTRUCT }
-constructor gamma_ctrl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y );
-
- m_background_color.ConstrDbl (1.0 ,1.0 ,0.9 );
- m_border_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_curve_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_grid_color.ConstrDbl (0.2 ,0.2 ,0.0 );
- m_inactive_pnt_color.ConstrDbl(0.0 ,0.0 ,0.0 );
- m_active_pnt_color.ConstrDbl (1.0 ,0.0 ,0.0 );
- m_text_color.ConstrDbl (0.0 ,0.0 ,0.0 );
-
- m_colors[0 ]:=@m_background_color;
- m_colors[1 ]:=@m_border_color;
- m_colors[2 ]:=@m_curve_color;
- m_colors[3 ]:=@m_grid_color;
- m_colors[4 ]:=@m_inactive_pnt_color;
- m_colors[5 ]:=@m_active_pnt_color;
- m_colors[6 ]:=@m_text_color;
-
-end;
-
-{ BACKGROUND_COLOR_ }
-procedure gamma_ctrl.background_color_;
-begin
- m_background_color:=c^;
-
-end;
-
-{ BORDER_COLOR_ }
-procedure gamma_ctrl.border_color_;
-begin
- m_border_color:=c^;
-
-end;
-
-{ CURVE_COLOR_ }
-procedure gamma_ctrl.curve_color_;
-begin
- m_curve_color:=c^;
-
-end;
-
-{ GRID_COLOR_ }
-procedure gamma_ctrl.grid_color_;
-begin
- m_grid_color:=c^;
-
-end;
-
-{ INACTIVE_PNT_COLOR_ }
-procedure gamma_ctrl.inactive_pnt_color_;
-begin
- m_inactive_pnt_color:=c^;
-
-end;
-
-{ ACTIVE_PNT_COLOR_ }
-procedure gamma_ctrl.active_pnt_color_;
-begin
- m_active_pnt_color:=c^;
-
-end;
-
-{ TEXT_COLOR_ }
-procedure gamma_ctrl.text_color_;
-begin
- m_text_color:=c^;
-
-end;
-
-{ _COLOR }
-function gamma_ctrl._color;
-begin
- result:=m_colors[i ];
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 30.01.2006-Milano: Unit port establishment +// +{ agg_gamma_ctrl.pas } +unit + agg_gamma_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + SysUtils , + agg_basics , + agg_gamma_spline , + agg_ellipse , + agg_conv_stroke , + agg_gsv_text , + agg_trans_affine , + agg_color , + agg_ctrl , + agg_math , + agg_math_stroke ; + +{ TYPES DEFINITION } +type + gamma_ctrl_impl = object(ctrl ) + m_gamma_spline : gamma_spline; + + m_border_width , + m_border_extra , + m_curve_width , + m_grid_width , + m_text_thickness , + m_point_size , + m_text_height , + m_text_width , + + m_xc1 , + m_yc1 , + m_xc2 , + m_yc2 , + m_xs1 , + m_ys1 , + m_xs2 , + m_ys2 , + m_xt1 , + m_yt1 , + m_xt2 , + m_yt2 : double; + + m_curve_poly : conv_stroke; + m_ellipse : ellipse; + m_text : gsv_text; + m_text_poly : conv_stroke; + + m_idx , + m_vertex : unsigned; + + m_vx , + m_vy : array[0..31 ] of double; + + m_xp1 , + m_yp1 , + m_xp2 , + m_yp2 : double; + + m_p1_active : boolean; + m_mouse_point : unsigned; + + m_pdx , + m_pdy : double; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false ); + destructor Destruct; virtual; + + // Set other parameters + procedure border_width_ (t : double; extra : double = 0.0 ); + procedure curve_width_ (t : double ); + procedure grid_width_ (t : double ); + procedure text_thickness_(t : double ); + procedure text_size_ (h : double; w : double = 0.0 ); + procedure point_size_ (s : double ); + + // Event handlers. Just call them if the respective events + // in your system occure. The functions return true if redrawing + // is required. + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + procedure change_active_point; + + // A copy of gamma_spline interface + procedure values(kx1 ,ky1 ,kx2 ,ky2 : double ); overload; + procedure values(kx1 ,ky1 ,kx2 ,ky2 : double_ptr ); overload; + + function gamma : char_ptr; + function _y(x : double ) : double; + + function func_operator_gamma(x : double ) : double; virtual; + + // Vertex soutce interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + // Private + procedure calc_spline_box; + procedure calc_points; + procedure calc_values; + + end; + + gamma_ctrl = object(gamma_ctrl_impl ) + m_background_color , + m_border_color , + m_curve_color , + m_grid_color , + m_inactive_pnt_color , + m_active_pnt_color , + m_text_color : aggclr; + + m_colors : array[0..6 ] of aggclr_ptr; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false ); + + procedure background_color_ (c : aggclr_ptr ); + procedure border_color_ (c : aggclr_ptr ); + procedure curve_color_ (c : aggclr_ptr ); + procedure grid_color_ (c : aggclr_ptr ); + procedure inactive_pnt_color_(c : aggclr_ptr ); + procedure active_pnt_color_ (c : aggclr_ptr ); + procedure text_color_ (c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor gamma_ctrl_impl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y ); + + m_border_width :=2.0; + m_border_extra :=0.0; + m_curve_width :=2.0; + m_grid_width :=0.2; + m_text_thickness:=1.5; + m_point_size :=5.0; + m_text_height :=9.0; + m_text_width :=0.0; + + m_xc1:=x1; + m_yc1:=y1; + m_xc2:=x2; + m_yc2:=y2 - m_text_height * 2.0; + m_xt1:=x1; + m_yt1:=y2 - m_text_height * 2.0; + m_xt2:=x2; + m_yt2:=y2; + + m_gamma_spline.Construct; + m_ellipse.Construct; + m_curve_poly.Construct(@m_gamma_spline ); + m_text.Construct; + m_text_poly.Construct (@m_text ); + + m_idx :=0; + m_vertex:=0; + + m_p1_active :=true; + m_mouse_point:=0; + + m_pdx:=0.0; + m_pdy:=0.0; + + calc_spline_box; + +end; + +{ DESTRUCT } +destructor gamma_ctrl_impl.Destruct; +begin + m_gamma_spline.Destruct; + m_curve_poly.Destruct; + m_text.Destruct; + m_text_poly.Destruct; + +end; + +{ BORDER_WIDTH_ } +procedure gamma_ctrl_impl.border_width_; +begin + m_border_width:=t; + m_border_extra:=extra; + + calc_spline_box; + +end; + +{ CURVE_WIDTH_ } +procedure gamma_ctrl_impl.curve_width_; +begin + m_curve_width:=t; + +end; + +{ GRID_WIDTH_ } +procedure gamma_ctrl_impl.grid_width_; +begin + m_grid_width:=t; + +end; + +{ TEXT_THICKNESS_ } +procedure gamma_ctrl_impl.text_thickness_; +begin + m_text_thickness:=t; + +end; + +{ TEXT_SIZE_ } +procedure gamma_ctrl_impl.text_size_; +begin + m_text_width :=w; + m_text_height:=h; + + m_yc2:=m_y2 - m_text_height * 2.0; + m_yt1:=m_y2 - m_text_height * 2.0; + + calc_spline_box; + +end; + +{ POINT_SIZE_ } +procedure gamma_ctrl_impl.point_size_; +begin + m_point_size:=s; + +end; + +{ IN_RECT } +function gamma_ctrl_impl.in_rect; +begin + inverse_transform_xy(@x ,@y ); + + result:= + (x >= m_x1 ) and + (x <= m_x2 ) and + (y >= m_y1 ) and + (y <= m_y2 ); + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function gamma_ctrl_impl.on_mouse_button_down; +begin + inverse_transform_xy(@x ,@y ); + calc_points; + + if calc_distance(x ,y ,m_xp1 ,m_yp1 ) <= m_point_size + 1 then + begin + m_mouse_point:=1; + + m_pdx:=m_xp1 - x; + m_pdy:=m_yp1 - y; + + m_p1_active:=true; + + result:=true; + + exit; + + end; + + if calc_distance(x ,y ,m_xp2 ,m_yp2 ) <= m_point_size + 1 then + begin + m_mouse_point:=2; + + m_pdx:=m_xp2 - x; + m_pdy:=m_yp2 - y; + + m_p1_active:=false; + + result:=true; + + exit; + + end; + + result:=false; + +end; + +{ ON_MOUSE_BUTTON_UP } +function gamma_ctrl_impl.on_mouse_button_up; +begin + if m_mouse_point <> 0 then + begin + m_mouse_point:=0; + + result:=true; + + end + else + result:=false; + +end; + +{ ON_MOUSE_MOVE } +function gamma_ctrl_impl.on_mouse_move; +begin + inverse_transform_xy(@x ,@y ); + + if not button_flag then + result:=on_mouse_button_up(x ,y ) + else + begin + if m_mouse_point = 1 then + begin + m_xp1:=x + m_pdx; + m_yp1:=y + m_pdy; + + calc_values; + + result:=true; + + exit; + + end; + + if m_mouse_point = 2 then + begin + m_xp2:=x + m_pdx; + m_yp2:=y + m_pdy; + + calc_values; + + result:=true; + + exit; + + end; + + result:=false; + + end; + +end; + +{ ON_ARROW_KEYS } +function gamma_ctrl_impl.on_arrow_keys; +var + kx1 ,ky1 ,kx2 ,ky2 : double; + + ret : boolean; + +begin + ret:=false; + + m_gamma_spline.values(@kx1 ,@ky1 ,@kx2 ,@ky2 ); + + if m_p1_active then + begin + if left then + begin + kx1:=kx1 - 0.005; + ret:=true; + + end; + + if right then + begin + kx1:=kx1 + 0.005; + ret:=true; + + end; + + if down then + begin + ky1:=ky1 - 0.005; + ret:=true; + + end; + + if up then + begin + ky1:=ky1 + 0.005; + ret:=true; + + end; + + end + else + begin + if left then + begin + kx2:=kx2 + 0.005; + ret:=true; + + end; + + if right then + begin + kx2:=kx2 - 0.005; + ret:=true; + + end; + + if down then + begin + ky2:=ky2 + 0.005; + ret:=true; + + end; + + if up then + begin + ky2:=ky2 - 0.005; + ret:= true; + + end; + + end; + + if ret then + m_gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 ); + + result:=ret; + +end; + +{ CHANGE_ACTIVE_POINT } +procedure gamma_ctrl_impl.change_active_point; +begin + if m_p1_active then + m_p1_active:=false + else + m_p1_active:=true; + +end; + +{ VALUES } +procedure gamma_ctrl_impl.values(kx1 ,ky1 ,kx2 ,ky2 : double ); +begin + m_gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 ); + +end; + +{ VALUES } +procedure gamma_ctrl_impl.values(kx1 ,ky1 ,kx2 ,ky2 : double_ptr ); +begin + m_gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 ); + +end; + +{ GAMMA } +function gamma_ctrl_impl.gamma; +begin + result:=m_gamma_spline.gamma; + +end; + +{ _Y } +function gamma_ctrl_impl._y; +begin + result:=m_gamma_spline._y(x ); + +end; + +{ FUNC_OPERATOR_GAMMA } +function gamma_ctrl_impl.func_operator_gamma; +begin + result:=m_gamma_spline._y(x ); + +end; + +{ NUM_PATHS } +function gamma_ctrl_impl.num_paths; +begin + result:=7; + +end; + +{ REWIND } +procedure gamma_ctrl_impl.rewind; +var + kx1 ,ky1 ,kx2 ,ky2 : double; + + tbuf : array[0..31 ] of char; + +begin + m_idx:=path_id; + + case path_id of + 0 : // Background + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1 - m_border_extra; + m_vy[0 ]:=m_y1 - m_border_extra; + m_vx[1 ]:=m_x2 + m_border_extra; + m_vy[1 ]:=m_y1 - m_border_extra; + m_vx[2 ]:=m_x2 + m_border_extra; + m_vy[2 ]:=m_y2 + m_border_extra; + m_vx[3 ]:=m_x1 - m_border_extra; + m_vy[3 ]:=m_y2 + m_border_extra; + + end; + + 1 : // Border + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1; + m_vy[0 ]:=m_y1; + m_vx[1 ]:=m_x2; + m_vy[1 ]:=m_y1; + m_vx[2 ]:=m_x2; + m_vy[2 ]:=m_y2; + m_vx[3 ]:=m_x1; + m_vy[3 ]:=m_y2; + m_vx[4 ]:=m_x1 + m_border_width; + m_vy[4 ]:=m_y1 + m_border_width; + m_vx[5 ]:=m_x1 + m_border_width; + m_vy[5 ]:=m_y2 - m_border_width; + m_vx[6 ]:=m_x2 - m_border_width; + m_vy[6 ]:=m_y2 - m_border_width; + m_vx[7 ]:=m_x2 - m_border_width; + m_vy[7 ]:=m_y1 + m_border_width; + m_vx[8 ]:=m_xc1 + m_border_width; + m_vy[8 ]:=m_yc2 - m_border_width * 0.5; + m_vx[9 ]:=m_xc2 - m_border_width; + m_vy[9 ]:=m_yc2 - m_border_width * 0.5; + m_vx[10 ]:=m_xc2 - m_border_width; + m_vy[10 ]:=m_yc2 + m_border_width * 0.5; + m_vx[11 ]:=m_xc1 + m_border_width; + m_vy[11 ]:=m_yc2 + m_border_width * 0.5; + + end; + + 2 : // Curve + begin + m_gamma_spline.box(m_xs1 ,m_ys1 ,m_xs2 ,m_ys2 ); + + m_curve_poly.width_(m_curve_width ); + m_curve_poly.rewind(0 ); + + end; + + 3 : // Grid + begin + m_vertex:=0; + + m_vx[0 ]:=m_xs1; + m_vy[0 ]:=(m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; + m_vx[1 ]:=m_xs2; + m_vy[1 ]:=(m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; + m_vx[2 ]:=m_xs2; + m_vy[2 ]:=(m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; + m_vx[3 ]:=m_xs1; + m_vy[3 ]:=(m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; + m_vx[4 ]:=(m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; + m_vy[4 ]:=m_ys1; + m_vx[5 ]:=(m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; + m_vy[5 ]:=m_ys2; + m_vx[6 ]:=(m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; + m_vy[6 ]:=m_ys2; + m_vx[7 ]:=(m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; + m_vy[7 ]:=m_ys1; + + calc_points; + + m_vx[8 ]:=m_xs1; + m_vy[8 ]:=m_yp1 - m_grid_width * 0.5; + m_vx[9 ]:=m_xp1 - m_grid_width * 0.5; + m_vy[9 ]:=m_yp1 - m_grid_width * 0.5; + m_vx[10 ]:=m_xp1 - m_grid_width * 0.5; + m_vy[10 ]:=m_ys1; + m_vx[11 ]:=m_xp1 + m_grid_width * 0.5; + m_vy[11 ]:=m_ys1; + m_vx[12 ]:=m_xp1 + m_grid_width * 0.5; + m_vy[12 ]:=m_yp1 + m_grid_width * 0.5; + m_vx[13 ]:=m_xs1; + m_vy[13 ]:=m_yp1 + m_grid_width * 0.5; + m_vx[14 ]:=m_xs2; + m_vy[14 ]:=m_yp2 + m_grid_width * 0.5; + m_vx[15 ]:=m_xp2 + m_grid_width * 0.5; + m_vy[15 ]:=m_yp2 + m_grid_width * 0.5; + m_vx[16 ]:=m_xp2 + m_grid_width * 0.5; + m_vy[16 ]:=m_ys2; + m_vx[17 ]:=m_xp2 - m_grid_width * 0.5; + m_vy[17 ]:=m_ys2; + m_vx[18 ]:=m_xp2 - m_grid_width * 0.5; + m_vy[18 ]:=m_yp2 - m_grid_width * 0.5; + m_vx[19 ]:=m_xs2; + m_vy[19 ]:=m_yp2 - m_grid_width * 0.5; + + end; + + 4 : // Point1 + begin + calc_points; + + if m_p1_active then + m_ellipse.init(m_xp2 ,m_yp2 ,m_point_size ,m_point_size ,32 ) + else + m_ellipse.init(m_xp1 ,m_yp1 ,m_point_size ,m_point_size ,32 ); + + end; + + 5 : // Point2 + begin + calc_points; + + if m_p1_active then + m_ellipse.init(m_xp1 ,m_yp1 ,m_point_size ,m_point_size ,32 ) + else + m_ellipse.init(m_xp2 ,m_yp2 ,m_point_size ,m_point_size ,32 ); + + end; + + 6 : // Text + begin + m_gamma_spline.values(@kx1 ,@ky1 ,@kx2 ,@ky2 ); + + sprintf(@tbuf[0] , '%.3f '#0 ,kx1 ); + sprintf(@tbuf[StrLen(@tbuf[0 ] ) ] ,'%.3f '#0 ,ky1 ); + sprintf(@tbuf[StrLen(@tbuf[0 ] ) ] ,'%.3f '#0 ,kx2 ); + sprintf(@tbuf[StrLen(@tbuf[0 ] ) ] ,'%.3f'#0 ,ky2 ); + + m_text.text_(@tbuf[0 ] ); + m_text.size_(m_text_height ,m_text_width ); + + m_text.start_point_(m_xt1 + m_border_width * 2.0 ,(m_yt1 + m_yt2 ) * 0.5 - m_text_height * 0.5 ); + m_text_poly.width_(m_text_thickness ); + + m_text_poly.line_join_(round_join ); + m_text_poly.line_cap_ (round_cap ); + + m_text_poly.rewind(0); + + end; + + end; + +end; + +{ VERTEX } +function gamma_ctrl_impl.vertex; +var + cmd : unsigned; + +begin + cmd:=path_cmd_line_to; + + case m_idx of + 0 : + begin + if m_vertex = 0 then + cmd:=path_cmd_move_to; + + if m_vertex >= 4 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 1 : + begin + if (m_vertex = 0 ) or + (m_vertex = 4 ) or + (m_vertex = 8 ) then + cmd:=path_cmd_move_to; + + if m_vertex >= 12 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 2 : + cmd:=m_curve_poly.vertex(x ,y ); + + 3 : + begin + if (m_vertex = 0 ) or + (m_vertex = 4 ) or + (m_vertex = 8 ) or + (m_vertex = 14 ) then + cmd:=path_cmd_move_to; + + if m_vertex >= 20 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 4 ,5 : + cmd:=m_ellipse.vertex(x ,y ); + + 6 : + cmd:=m_text_poly.vertex(x ,y ); + + else + cmd:=path_cmd_stop; + + end; + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ CALC_SPLINE_BOX } +procedure gamma_ctrl_impl.calc_spline_box; +begin + m_xs1:=m_xc1 + m_border_width; + m_ys1:=m_yc1 + m_border_width; + m_xs2:=m_xc2 - m_border_width; + m_ys2:=m_yc2 - m_border_width * 0.5; + +end; + +{ CALC_POINTS } +procedure gamma_ctrl_impl.calc_points; +var + kx1 ,ky1 ,kx2 ,ky2 : double; + +begin + m_gamma_spline.values(@kx1 ,@ky1 ,@kx2 ,@ky2 ); + + m_xp1:=m_xs1 + (m_xs2 - m_xs1 ) * kx1 * 0.25; + m_yp1:=m_ys1 + (m_ys2 - m_ys1 ) * ky1 * 0.25; + m_xp2:=m_xs2 - (m_xs2 - m_xs1 ) * kx2 * 0.25; + m_yp2:=m_ys2 - (m_ys2 - m_ys1 ) * ky2 * 0.25; + +end; + +{ CALC_VALUES } +procedure gamma_ctrl_impl.calc_values; +var + kx1 ,ky1 ,kx2 ,ky2 : double; + +begin + kx1:=(m_xp1 - m_xs1 ) * 4.0 / (m_xs2 - m_xs1 ); + ky1:=(m_yp1 - m_ys1 ) * 4.0 / (m_ys2 - m_ys1 ); + kx2:=(m_xs2 - m_xp2 ) * 4.0 / (m_xs2 - m_xs1 ); + ky2:=(m_ys2 - m_yp2 ) * 4.0 / (m_ys2 - m_ys1 ); + + m_gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 ); + +end; + +{ CONSTRUCT } +constructor gamma_ctrl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y ); + + m_background_color.ConstrDbl (1.0 ,1.0 ,0.9 ); + m_border_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_curve_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_grid_color.ConstrDbl (0.2 ,0.2 ,0.0 ); + m_inactive_pnt_color.ConstrDbl(0.0 ,0.0 ,0.0 ); + m_active_pnt_color.ConstrDbl (1.0 ,0.0 ,0.0 ); + m_text_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + + m_colors[0 ]:=@m_background_color; + m_colors[1 ]:=@m_border_color; + m_colors[2 ]:=@m_curve_color; + m_colors[3 ]:=@m_grid_color; + m_colors[4 ]:=@m_inactive_pnt_color; + m_colors[5 ]:=@m_active_pnt_color; + m_colors[6 ]:=@m_text_color; + +end; + +{ BACKGROUND_COLOR_ } +procedure gamma_ctrl.background_color_; +begin + m_background_color:=c^; + +end; + +{ BORDER_COLOR_ } +procedure gamma_ctrl.border_color_; +begin + m_border_color:=c^; + +end; + +{ CURVE_COLOR_ } +procedure gamma_ctrl.curve_color_; +begin + m_curve_color:=c^; + +end; + +{ GRID_COLOR_ } +procedure gamma_ctrl.grid_color_; +begin + m_grid_color:=c^; + +end; + +{ INACTIVE_PNT_COLOR_ } +procedure gamma_ctrl.inactive_pnt_color_; +begin + m_inactive_pnt_color:=c^; + +end; + +{ ACTIVE_PNT_COLOR_ } +procedure gamma_ctrl.active_pnt_color_; +begin + m_active_pnt_color:=c^; + +end; + +{ TEXT_COLOR_ } +procedure gamma_ctrl.text_color_; +begin + m_text_color:=c^; + +end; + +{ _COLOR } +function gamma_ctrl._color; +begin + result:=m_colors[i ]; + +end; + +END. + diff --git a/src/corelib/render/software/ctrl/agg_gamma_spline.pas b/src/corelib/render/software/ctrl/agg_gamma_spline.pas index 7be50692..e061955c 100644 --- a/src/corelib/render/software/ctrl/agg_gamma_spline.pas +++ b/src/corelib/render/software/ctrl/agg_gamma_spline.pas @@ -1,265 +1,265 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 30.01.2006-Milano: Unit port establishment
-//
-{ agg_gamma_spline.pas }
-unit
- agg_gamma_spline ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- agg_basics ,
- agg_bspline ,
- agg_vertex_source ;
-
-{ TYPES DEFINITION }
-type
-// Class-helper for calculation gamma-correction arrays. A gamma-correction
-// array is an array of 256 unsigned chars that determine the actual values
-// of Anti-Aliasing for each pixel coverage value from 0 to 255. If all the
-// values in the array are equal to its index, i.e. 0,1,2,3,... there's
-// no gamma-correction. Class agg::polyfill allows you to use custom
-// gamma-correction arrays. You can calculate it using any approach, and
-// class gamma_spline allows you to calculate almost any reasonable shape
-// of the gamma-curve with using only 4 values - kx1, ky1, kx2, ky2.
-//
-// kx2
-// +----------------------------------+
-// | | | . |
-// | | | . | ky2
-// | | . ------|
-// | | . |
-// | | . |
-// |----------------.|----------------|
-// | . | |
-// | . | |
-// |-------. | |
-// ky1 | . | | |
-// | . | | |
-// +----------------------------------+
-// kx1
-//
-// Each value can be in range [0...2]. Value 1.0 means one quarter of the
-// bounding rectangle. Function values() calculates the curve by these
-// 4 values. After calling it one can get the gamma-array with call gamma().
-// Class also supports the vertex source interface, i.e rewind() and
-// vertex(). It's made for convinience and used in class gamma_ctrl.
-// Before calling rewind/vertex one must set the bounding box
-// box() using pixel coordinates.
- gamma_spline = object(vertex_source )
- m_gamma : array[0..255 ] of char;
-
- m_x ,
- m_y : array[0..3 ] of double;
- m_x1 ,
- m_y1 ,
- m_x2 ,
- m_y2 ,
-
- m_cur_x : double;
- m_spline : bspline;
-
- constructor Construct;
- destructor Destruct; virtual;
-
- procedure values(kx1 ,ky1 ,kx2 ,ky2 : double ); overload;
- procedure values(kx1 ,ky1 ,kx2 ,ky2 : double_ptr ); overload;
-
- function gamma : char_ptr;
- function _y (x : double ) : double;
- procedure box(x1 ,y1 ,x2 ,y2 : double );
-
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor gamma_spline.Construct;
-begin
- m_spline.Construct;
-
- m_x1:=0;
- m_y1:=0;
- m_x2:=10;
- m_y2:=10;
-
- m_cur_x:=0.0;
-
- values(1.0 ,1.0 ,1.0 ,1.0 );
-
-end;
-
-{ DESTRUCT }
-destructor gamma_spline.Destruct;
-begin
- m_spline.Destruct;
-
-end;
-
-{ VALUES }
-procedure gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 : double );
-var
- i : int;
-
-begin
- if kx1 < 0.001 then
- kx1:=0.001;
-
- if kx1 > 1.999 then
- kx1:=1.999;
-
- if ky1 < 0.001 then
- ky1:=0.001;
-
- if ky1 > 1.999 then
- ky1:=1.999;
-
- if kx2 < 0.001 then
- kx2:=0.001;
-
- if kx2 > 1.999 then
- kx2:=1.999;
-
- if ky2 < 0.001 then
- ky2:=0.001;
-
- if ky2 > 1.999 then
- ky2:=1.999;
-
- m_x[0 ]:=0.0;
- m_y[0 ]:=0.0;
- m_x[1 ]:=kx1 * 0.25;
- m_y[1 ]:=ky1 * 0.25;
- m_x[2 ]:=1.0 - kx2 * 0.25;
- m_y[2 ]:=1.0 - ky2 * 0.25;
- m_x[3 ]:=1.0;
- m_y[3 ]:=1.0;
-
- m_spline.init(4 ,@m_x ,@m_y );
-
- for i:=0 to 255 do
- m_gamma[i ]:=char(trunc(_y(i / 255.0 ) * 255.0 ) );
-
-end;
-
-{ VALUES }
-procedure gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 : double_ptr );
-begin
- kx1^:=m_x[1 ] * 4.0;
- ky1^:=m_y[1 ] * 4.0;
- kx2^:=(1.0 - m_x[2 ] ) * 4.0;
- ky2^:=(1.0 - m_y[2 ] ) * 4.0;
-
-end;
-
-{ GAMMA }
-function gamma_spline.gamma;
-begin
- result:=@m_gamma[0 ];
-
-end;
-
-{ _Y }
-function gamma_spline._y;
-var
- val : double;
-
-begin
- if x < 0.0 then
- x:=0.0;
-
- if x > 1.0 then
- x:=1.0;
-
- val:=m_spline.get(x );
-
- if val < 0.0 then
- val:=0.0;
-
- if val > 1.0 then
- val:=1.0;
-
- result:=val;
-
-end;
-
-{ BOX }
-procedure gamma_spline.box;
-begin
- m_x1:=x1;
- m_y1:=y1;
- m_x2:=x2;
- m_y2:=y2;
-
-end;
-
-{ REWIND }
-procedure gamma_spline.rewind;
-begin
- m_cur_x:=0.0;
-
-end;
-
-{ VERTEX }
-function gamma_spline.vertex;
-begin
- if m_cur_x = 0.0 then
- begin
- x^:=m_x1;
- y^:=m_y1;
-
- m_cur_x:=m_cur_x + (1.0 / (m_x2 - m_x1 ) );
- result :=path_cmd_move_to;
-
- exit;
-
- end;
-
- if m_cur_x > 1.0 then
- begin
- result:=path_cmd_stop;
-
- exit;
-
- end;
-
- x^:=m_x1 + m_cur_x * (m_x2 - m_x1 );
- y^:=m_y1 + _y(m_cur_x ) * (m_y2 - m_y1 );
-
- m_cur_x:=m_cur_x + (1.0 / (m_x2 - m_x1 ) );
- result :=path_cmd_line_to;
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 30.01.2006-Milano: Unit port establishment +// +{ agg_gamma_spline.pas } +unit + agg_gamma_spline ; + +INTERFACE + +{$I agg_mode.inc } + +uses + agg_basics , + agg_bspline , + agg_vertex_source ; + +{ TYPES DEFINITION } +type +// Class-helper for calculation gamma-correction arrays. A gamma-correction +// array is an array of 256 unsigned chars that determine the actual values +// of Anti-Aliasing for each pixel coverage value from 0 to 255. If all the +// values in the array are equal to its index, i.e. 0,1,2,3,... there's +// no gamma-correction. Class agg::polyfill allows you to use custom +// gamma-correction arrays. You can calculate it using any approach, and +// class gamma_spline allows you to calculate almost any reasonable shape +// of the gamma-curve with using only 4 values - kx1, ky1, kx2, ky2. +// +// kx2 +// +----------------------------------+ +// | | | . | +// | | | . | ky2 +// | | . ------| +// | | . | +// | | . | +// |----------------.|----------------| +// | . | | +// | . | | +// |-------. | | +// ky1 | . | | | +// | . | | | +// +----------------------------------+ +// kx1 +// +// Each value can be in range [0...2]. Value 1.0 means one quarter of the +// bounding rectangle. Function values() calculates the curve by these +// 4 values. After calling it one can get the gamma-array with call gamma(). +// Class also supports the vertex source interface, i.e rewind() and +// vertex(). It's made for convinience and used in class gamma_ctrl. +// Before calling rewind/vertex one must set the bounding box +// box() using pixel coordinates. + gamma_spline = object(vertex_source ) + m_gamma : array[0..255 ] of char; + + m_x , + m_y : array[0..3 ] of double; + m_x1 , + m_y1 , + m_x2 , + m_y2 , + + m_cur_x : double; + m_spline : bspline; + + constructor Construct; + destructor Destruct; virtual; + + procedure values(kx1 ,ky1 ,kx2 ,ky2 : double ); overload; + procedure values(kx1 ,ky1 ,kx2 ,ky2 : double_ptr ); overload; + + function gamma : char_ptr; + function _y (x : double ) : double; + procedure box(x1 ,y1 ,x2 ,y2 : double ); + + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor gamma_spline.Construct; +begin + m_spline.Construct; + + m_x1:=0; + m_y1:=0; + m_x2:=10; + m_y2:=10; + + m_cur_x:=0.0; + + values(1.0 ,1.0 ,1.0 ,1.0 ); + +end; + +{ DESTRUCT } +destructor gamma_spline.Destruct; +begin + m_spline.Destruct; + +end; + +{ VALUES } +procedure gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 : double ); +var + i : int; + +begin + if kx1 < 0.001 then + kx1:=0.001; + + if kx1 > 1.999 then + kx1:=1.999; + + if ky1 < 0.001 then + ky1:=0.001; + + if ky1 > 1.999 then + ky1:=1.999; + + if kx2 < 0.001 then + kx2:=0.001; + + if kx2 > 1.999 then + kx2:=1.999; + + if ky2 < 0.001 then + ky2:=0.001; + + if ky2 > 1.999 then + ky2:=1.999; + + m_x[0 ]:=0.0; + m_y[0 ]:=0.0; + m_x[1 ]:=kx1 * 0.25; + m_y[1 ]:=ky1 * 0.25; + m_x[2 ]:=1.0 - kx2 * 0.25; + m_y[2 ]:=1.0 - ky2 * 0.25; + m_x[3 ]:=1.0; + m_y[3 ]:=1.0; + + m_spline.init(4 ,@m_x ,@m_y ); + + for i:=0 to 255 do + m_gamma[i ]:=char(trunc(_y(i / 255.0 ) * 255.0 ) ); + +end; + +{ VALUES } +procedure gamma_spline.values(kx1 ,ky1 ,kx2 ,ky2 : double_ptr ); +begin + kx1^:=m_x[1 ] * 4.0; + ky1^:=m_y[1 ] * 4.0; + kx2^:=(1.0 - m_x[2 ] ) * 4.0; + ky2^:=(1.0 - m_y[2 ] ) * 4.0; + +end; + +{ GAMMA } +function gamma_spline.gamma; +begin + result:=@m_gamma[0 ]; + +end; + +{ _Y } +function gamma_spline._y; +var + val : double; + +begin + if x < 0.0 then + x:=0.0; + + if x > 1.0 then + x:=1.0; + + val:=m_spline.get(x ); + + if val < 0.0 then + val:=0.0; + + if val > 1.0 then + val:=1.0; + + result:=val; + +end; + +{ BOX } +procedure gamma_spline.box; +begin + m_x1:=x1; + m_y1:=y1; + m_x2:=x2; + m_y2:=y2; + +end; + +{ REWIND } +procedure gamma_spline.rewind; +begin + m_cur_x:=0.0; + +end; + +{ VERTEX } +function gamma_spline.vertex; +begin + if m_cur_x = 0.0 then + begin + x^:=m_x1; + y^:=m_y1; + + m_cur_x:=m_cur_x + (1.0 / (m_x2 - m_x1 ) ); + result :=path_cmd_move_to; + + exit; + + end; + + if m_cur_x > 1.0 then + begin + result:=path_cmd_stop; + + exit; + + end; + + x^:=m_x1 + m_cur_x * (m_x2 - m_x1 ); + y^:=m_y1 + _y(m_cur_x ) * (m_y2 - m_y1 ); + + m_cur_x:=m_cur_x + (1.0 / (m_x2 - m_x1 ) ); + result :=path_cmd_line_to; + +end; + +END. + diff --git a/src/corelib/render/software/ctrl/agg_polygon_ctrl.pas b/src/corelib/render/software/ctrl/agg_polygon_ctrl.pas index 881c9d60..2aa16ed7 100644 --- a/src/corelib/render/software/ctrl/agg_polygon_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_polygon_ctrl.pas @@ -1,769 +1,769 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 23.06.2006-Milano: ptrcomp adjustments
-// 23.02.2006-Milano: Unit port establishment
-//
-{ agg_polygon_ctrl.pas }
-unit
- agg_polygon_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- Math ,
- agg_basics ,
- agg_conv_stroke ,
- agg_ellipse ,
- agg_color ,
- agg_ctrl ,
- agg_vertex_source ;
-
-{ TYPES DEFINITION }
-type
- simple_polygon_vertex_source = object(vertex_source )
- m_polygon : double_ptr;
- m_num_points ,
- m_vertex : unsigned;
- m_roundoff ,
- m_close : boolean;
-
- constructor Construct(polygon : double_ptr; np : unsigned; roundoff : boolean = false; close : boolean = true );
-
- procedure close_(f : boolean );
- function _close : boolean;
-
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- end;
-
- polygon_ctrl_impl = object(ctrl )
- m_polygon : double_ptr;
- m_num_points : unsigned;
-
- m_node ,
- m_edge : int;
-
- m_vs : simple_polygon_vertex_source;
- m_stroke : conv_stroke;
-
- m_ellipse : ellipse;
- m_point_radius : double;
- m_status : unsigned;
-
- m_dx ,
- m_dy : double;
-
- m_in_polygon_check : boolean;
-
- constructor Construct(np : unsigned; point_radius : double = 5 );
- destructor Destruct; virtual;
-
- function _num_points : unsigned;
-
- function _xn(n : unsigned ) : double;
- function _yn(n : unsigned ) : double;
-
- function xn_ptr(n : unsigned ) : double_ptr;
- function yn_ptr(n : unsigned ) : double_ptr;
-
- function _polygon : double_ptr;
-
- procedure line_width_(w : double );
- function _line_width : double;
-
- procedure point_radius_(r : double );
- function _point_radius : double;
-
- procedure in_polygon_check_(f : boolean );
- function _in_polygon_check : boolean;
-
- procedure close_(f : boolean );
- function _close : boolean;
-
- // Vertex source interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- // Event handlers
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- // Private
- function check_edge (i : unsigned; x ,y : double ) : boolean;
- function point_in_polygon(x ,y : double ) : boolean;
-
- end;
-
- polygon_ctrl = object(polygon_ctrl_impl )
- m_color : aggclr;
-
- constructor Construct(np : unsigned; point_radius : double = 5 );
-
- procedure line_color_(c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor simple_polygon_vertex_source.Construct;
-begin
- m_polygon :=polygon;
- m_num_points:=np;
- m_vertex :=0;
- m_roundoff :=roundoff;
- m_close :=close;
-
-end;
-
-{ CLOSE_ }
-procedure simple_polygon_vertex_source.close_;
-begin
- m_close:=f;
-
-end;
-
-{ _CLOSE }
-function simple_polygon_vertex_source._close;
-begin
- result:=m_close;
-
-end;
-
-{ REWIND }
-procedure simple_polygon_vertex_source.rewind;
-begin
- m_vertex:=0;
-
-end;
-
-{ VERTEX }
-function simple_polygon_vertex_source.vertex;
-begin
- if m_vertex > m_num_points then
- begin
- result:=path_cmd_stop;
-
- exit;
-
- end;
-
- if m_vertex = m_num_points then
- begin
- inc(m_vertex );
-
- if m_close then
- result:=path_cmd_end_poly or path_flags_close
- else
- result:=path_cmd_end_poly or 0;
-
- exit;
-
- end;
-
- x^:=double_ptr(ptrcomp(m_polygon ) + (m_vertex * 2 ) * sizeof(double ) )^;
- y^:=double_ptr(ptrcomp(m_polygon ) + (m_vertex * 2 + 1 ) * sizeof(double ) )^;
-
- if m_roundoff then
- begin
- x^:=Floor(x^ ) + 0.5;
- y^:=Floor(y^ ) + 0.5;
-
- end;
-
- inc(m_vertex );
-
- if m_vertex = 1 then
- result:=path_cmd_move_to
- else
- result:=path_cmd_line_to;
-
-end;
-
-{ CONSTRUCT }
-constructor polygon_ctrl_impl.Construct;
-begin
- inherited Construct(0 ,0 ,1 ,1 ,false );
-
- agg_getmem(pointer(m_polygon ) ,np * 2 * sizeof(double ) );
-
- m_num_points:=np;
-
- m_node:=-1;
- m_edge:=-1;
-
- m_vs.Construct (m_polygon ,m_num_points ,false );
- m_stroke.Construct(@m_vs );
- m_ellipse.Construct;
-
- m_point_radius:=point_radius;
-
- m_status:=0;
-
- m_dx:=0.0;
- m_dy:=0.0;
-
- m_in_polygon_check:=false;
-
- m_stroke.width_(1.0 );
-
-end;
-
-{ DESTRUCT }
-destructor polygon_ctrl_impl.Destruct;
-begin
- agg_freemem(pointer(m_polygon ) ,m_num_points * 2 * sizeof(double ) );
-
- m_stroke.Destruct;
-
-end;
-
-{ _NUM_POINTS }
-function polygon_ctrl_impl._num_points;
-begin
- result:=m_num_points;
-
-end;
-
-{ _XN }
-function polygon_ctrl_impl._xn;
-begin
- result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 ) * sizeof(double ) )^;
-
-end;
-
-{ _YN }
-function polygon_ctrl_impl._yn;
-begin
- result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 + 1 ) * sizeof(double ) )^;
-
-end;
-
-{ XN_PTR }
-function polygon_ctrl_impl.xn_ptr;
-begin
- result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 ) * sizeof(double ) );
-
-end;
-
-{ YN_PTR }
-function polygon_ctrl_impl.yn_ptr;
-begin
- result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 + 1 ) * sizeof(double ) );
-
-end;
-
-{ _POLYGON }
-function polygon_ctrl_impl._polygon;
-begin
- result:=m_polygon;
-
-end;
-
-{ LINE_WIDTH_ }
-procedure polygon_ctrl_impl.line_width_;
-begin
- m_stroke.width_(w );
-
-end;
-
-{ _LINE_WIDTH }
-function polygon_ctrl_impl._line_width;
-begin
- result:=m_stroke._width;
-
-end;
-
-{ POINT_RADIUS_ }
-procedure polygon_ctrl_impl.point_radius_;
-begin
- m_point_radius:=r;
-
-end;
-
-{ _POINT_RADIUS }
-function polygon_ctrl_impl._point_radius;
-begin
- result:=m_point_radius;
-
-end;
-
-{ IN_POLYGON_CHECK_ }
-procedure polygon_ctrl_impl.in_polygon_check_;
-begin
- m_in_polygon_check:=f;
-
-end;
-
-{ _IN_POLYGON_CHECK }
-function polygon_ctrl_impl._in_polygon_check;
-begin
- result:=m_in_polygon_check;
-
-end;
-
-{ CLOSE_ }
-procedure polygon_ctrl_impl.close_;
-begin
- m_vs.close_(f );
-
-end;
-
-{ _CLOSE }
-function polygon_ctrl_impl._close;
-begin
- result:=m_vs._close;
-
-end;
-
-{ NUM_PATHS }
-function polygon_ctrl_impl.num_paths;
-begin
- result:=1;
-
-end;
-
-{ REWIND }
-procedure polygon_ctrl_impl.rewind;
-begin
- m_status:=0;
-
- m_stroke.rewind(0 );
-
-end;
-
-{ VERTEX }
-function polygon_ctrl_impl.vertex;
-var
- cmd : unsigned;
- r : double;
-
-begin
- cmd:=path_cmd_stop;
- r :=m_point_radius;
-
- if m_status = 0 then
- begin
- cmd:=m_stroke.vertex(x ,y );
-
- if not is_stop(cmd ) then
- begin
- transform_xy(x ,y );
-
- result:=cmd;
-
- exit;
-
- end;
-
- if (m_node >= 0 ) and
- (m_node = m_status ) then
- r:=r * 1.2;
-
- m_ellipse.init(_xn(m_status ) ,_yn(m_status ) ,r ,r ,32 );
-
- inc(m_status );
-
- end;
-
- cmd:=m_ellipse.vertex(x ,y );
-
- if not is_stop(cmd ) then
- begin
- transform_xy(x ,y );
-
- result:=cmd;
-
- exit;
-
- end;
-
- if m_status >= m_num_points then
- begin
- result:=path_cmd_stop;
-
- exit;
-
- end;
-
- if (m_node >= 0 ) and
- (m_node = m_status ) then
- r:=r * 1.2;
-
- m_ellipse.init(_xn(m_status ) ,_yn(m_status ) ,r ,r ,32 );
-
- inc(m_status );
-
- cmd:=m_ellipse.vertex(x ,y );
-
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ IN_RECT }
-function polygon_ctrl_impl.in_rect;
-begin
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function polygon_ctrl_impl.on_mouse_button_down;
-var
- i : unsigned;
- ret : boolean;
-
-begin
- ret:=false;
-
- m_node:=-1;
- m_edge:=-1;
-
- inverse_transform_xy(@x ,@y );
-
- for i:=0 to m_num_points - 1 do
- if Sqrt((x - _xn(i ) ) * (x - _xn(i ) ) + (y - _yn(i ) ) * (y - _yn(i ) ) ) < m_point_radius then
- begin
- m_dx :=x - _xn(i );
- m_dy :=y - _yn(i );
- m_node:=i;
- ret :=true;
-
- break;
-
- end;
-
- if not ret then
- for i:=0 to m_num_points - 1 do
- if check_edge(i ,x ,y ) then
- begin
- m_dx :=x;
- m_dy :=y;
- m_edge:=i;
- ret :=true;
-
- break;
-
- end;
-
- if not ret then
- if point_in_polygon(x ,y ) then
- begin
- m_dx :=x;
- m_dy :=y;
- m_node:=m_num_points;
- ret :=true;
-
- end;
-
- result:=ret;
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function polygon_ctrl_impl.on_mouse_button_up;
-var
- ret : boolean;
-
-begin
- ret :=(m_node >= 0 ) or (m_edge >= 0 );
- m_node:=-1;
- m_edge:=-1;
- result:=ret;
-
-end;
-
-{ ON_MOUSE_MOVE }
-function polygon_ctrl_impl.on_mouse_move;
-var
- ret : boolean;
-
- i ,n1 ,n2 : unsigned;
-
- dx ,dy : double;
-
-begin
- ret:=false;
-
- inverse_transform_xy(@x ,@y );
-
- if m_node = m_num_points then
- begin
- dx:=x - m_dx;
- dy:=y - m_dy;
-
- for i:=0 to m_num_points - 1 do
- begin
- xn_ptr(i )^:=_xn(i ) + dx;
- yn_ptr(i )^:=_yn(i ) + dy;
-
- end;
-
- m_dx:=x;
- m_dy:=y;
- ret :=true;
-
- end
- else
- if m_edge >= 0 then
- begin
- n1:=m_edge;
- n2:=(n1 + m_num_points - 1 ) mod m_num_points;
- dx:=x - m_dx;
- dy:=y - m_dy;
-
- xn_ptr(n1 )^:=_xn(n1 ) + dx;
- yn_ptr(n1 )^:=_yn(n1 ) + dy;
- xn_ptr(n2 )^:=_xn(n2 ) + dx;
- yn_ptr(n2 )^:=_yn(n2 ) + dy;
-
- m_dx:=x;
- m_dy:=y;
- ret :=true;
-
- end
- else
- if m_node >= 0 then
- begin
- xn_ptr(m_node )^:=x - m_dx;
- yn_ptr(m_node )^:=y - m_dy;
-
- ret:=true;
-
- end;
-
- result:=ret;
-
-end;
-
-{ ON_ARROW_KEYS }
-function polygon_ctrl_impl.on_arrow_keys;
-begin
- result:=false;
-
-end;
-
-{ CHECK_EDGE }
-function polygon_ctrl_impl.check_edge;
-var
- ret : boolean;
-
- n1 ,n2 : unsigned;
-
- x1 ,y1 ,x2 ,y2 ,dx ,dy ,x3 ,y3 ,x4 ,y4 ,den ,u1 ,xi ,yi : double;
-
-begin
- ret:=false;
-
- n1:=i;
- n2:=(i + m_num_points - 1 ) mod m_num_points;
- x1:=_xn(n1 );
- y1:=_yn(n1 );
- x2:=_xn(n2 );
- y2:=_yn(n2 );
-
- dx:=x2 - x1;
- dy:=y2 - y1;
-
- if Sqrt(dx * dx + dy * dy ) > 0.0000001 then
- begin
- x3:=x;
- y3:=y;
- x4:=x3 - dy;
- y4:=y3 + dx;
-
- den:=(y4 - y3 ) * (x2 - x1 ) - (x4 - x3 ) * (y2 - y1 );
- u1 :=((x4 - x3 ) * (y1 - y3 ) - (y4 - y3 ) * (x1 - x3 ) ) / den;
-
- xi:=x1 + u1 * (x2 - x1 );
- yi:=y1 + u1 * (y2 - y1 );
-
- dx:=xi - x;
- dy:=yi - y;
-
- if (u1 > 0.0 ) and
- (u1 < 1.0 ) and
- (Sqrt(dx * dx + dy * dy ) <= m_point_radius ) then
- ret:=true;
-
- end;
-
- result:=ret;
-
-end;
-
-{ POINT_IN_POLYGON }
-//======= Crossings Multiply algorithm of InsideTest ========================
-//
-// By Eric Haines, 3D/Eye Inc, erich@eye.com
-//
-// This version is usually somewhat faster than the original published in
-// Graphics Gems IV; by turning the division for testing the X axis crossing
-// into a tricky multiplication test this part of the test became faster,
-// which had the additional effect of making the test for "both to left or
-// both to right" a bit slower for triangles than simply computing the
-// intersection each time. The main increase is in triangle testing speed,
-// which was about 15% faster; all other polygon complexities were pretty much
-// the same as before. On machines where division is very expensive (not the
-// case on the HP 9000 series on which I tested) this test should be much
-// faster overall than the old code. Your mileage may (in fact, will) vary,
-// depending on the machine and the test data, but in general I believe this
-// code is both shorter and faster. This test was inspired by unpublished
-// Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson.
-// Related work by Samosky is in:
-//
-// Samosky, Joseph, "SectionView: A system for interactively specifying and
-// visualizing sections through three-dimensional medical image data",
-// M.S. Thesis, Department of Electrical Engineering and Computer Science,
-// Massachusetts Institute of Technology, 1993.
-//
-// Shoot a test ray along +X axis. The strategy is to compare vertex Y values
-// to the testing point's Y and quickly discard edges which are entirely to one
-// side of the test ray. Note that CONVEX and WINDING code can be added as
-// for the CrossingsTest() code; it is left out here for clarity.
-//
-// Input 2D polygon _pgon_ with _numverts_ number of vertices and test point
-// _point_, returns 1 if inside, 0 if outside.
-function polygon_ctrl_impl.point_in_polygon;
-var
- j ,k : unsigned;
-
- yflag0 ,yflag1 ,inside_flag : int;
-
- vtx0 ,vty0 ,vtx1 ,vty1 : double;
-
-begin
- if m_num_points < 3 then
- begin
- result:=false;
-
- exit;
-
- end;
-
- if not m_in_polygon_check then
- begin
- result:=false;
-
- exit;
-
- end;
-
- vtx0:=_xn(m_num_points - 1 );
- vty0:=_yn(m_num_points - 1 );
-
-// get test bit for above/below X axis
- yflag0:=int(vty0 >= y);
-
- vtx1:=_xn(0 );
- vty1:=_yn(0 );
-
- inside_flag:=0;
-
- for j:=1 to m_num_points do
- begin
- yflag1:=int(vty1 >= y );
-
- // Check if endpoints straddle (are on opposite sides) of X axis
- // (i.e. the Y's differ); if so, +X ray could intersect this edge.
- // The old test also checked whether the endpoints are both to the
- // right or to the left of the test point. However, given the faster
- // intersection point computation used below, this test was found to
- // be a break-even proposition for most polygons and a loser for
- // triangles (where 50% or more of the edges which survive this test
- // will cross quadrants and so have to have the X intersection computed
- // anyway). I credit Joseph Samosky with inspiring me to try dropping
- // the "both left or both right" part of my code.
- if yflag0 <> yflag1 then
- // Check intersection of pgon segment with +X ray.
- // Note if >= point's X; if so, the ray hits it.
- // The division operation is avoided for the ">=" test by checking
- // the sign of the first vertex wrto the test point; idea inspired
- // by Joseph Samosky's and Mark Haigh-Hutchinson's different
- // polygon inclusion tests.
- if int((vty1 - y ) * (vtx0 - vtx1 ) >=
- (vtx1 - x ) * (vty0 - vty1 ) ) = yflag1 then
- inside_flag:=inside_flag xor 1;
-
- // Move to the next pair of vertices, retaining info as possible.
- yflag0:=yflag1;
- vtx0 :=vtx1;
- vty0 :=vty1;
-
- if j >= m_num_points then
- k:=j - m_num_points
- else
- k:=j;
-
- vtx1:=_xn(k );
- vty1:=_yn(k );
-
- end;
-
- result:=inside_flag <> 0;
-
-end;
-
-{ CONSTRUCT }
-constructor polygon_ctrl.Construct;
-begin
- inherited Construct(np ,point_radius );
-
- m_color.ConstrDbl(0.0 ,0.0 ,0.0 );
-
-end;
-
-{ LINE_COLOR_ }
-procedure polygon_ctrl.line_color_;
-begin
- m_color:=c^;
-
-end;
-
-{ _COLOR }
-function polygon_ctrl._color;
-begin
- result:=@m_color;
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 23.06.2006-Milano: ptrcomp adjustments +// 23.02.2006-Milano: Unit port establishment +// +{ agg_polygon_ctrl.pas } +unit + agg_polygon_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + Math , + agg_basics , + agg_conv_stroke , + agg_ellipse , + agg_color , + agg_ctrl , + agg_vertex_source ; + +{ TYPES DEFINITION } +type + simple_polygon_vertex_source = object(vertex_source ) + m_polygon : double_ptr; + m_num_points , + m_vertex : unsigned; + m_roundoff , + m_close : boolean; + + constructor Construct(polygon : double_ptr; np : unsigned; roundoff : boolean = false; close : boolean = true ); + + procedure close_(f : boolean ); + function _close : boolean; + + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + end; + + polygon_ctrl_impl = object(ctrl ) + m_polygon : double_ptr; + m_num_points : unsigned; + + m_node , + m_edge : int; + + m_vs : simple_polygon_vertex_source; + m_stroke : conv_stroke; + + m_ellipse : ellipse; + m_point_radius : double; + m_status : unsigned; + + m_dx , + m_dy : double; + + m_in_polygon_check : boolean; + + constructor Construct(np : unsigned; point_radius : double = 5 ); + destructor Destruct; virtual; + + function _num_points : unsigned; + + function _xn(n : unsigned ) : double; + function _yn(n : unsigned ) : double; + + function xn_ptr(n : unsigned ) : double_ptr; + function yn_ptr(n : unsigned ) : double_ptr; + + function _polygon : double_ptr; + + procedure line_width_(w : double ); + function _line_width : double; + + procedure point_radius_(r : double ); + function _point_radius : double; + + procedure in_polygon_check_(f : boolean ); + function _in_polygon_check : boolean; + + procedure close_(f : boolean ); + function _close : boolean; + + // Vertex source interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + // Event handlers + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Private + function check_edge (i : unsigned; x ,y : double ) : boolean; + function point_in_polygon(x ,y : double ) : boolean; + + end; + + polygon_ctrl = object(polygon_ctrl_impl ) + m_color : aggclr; + + constructor Construct(np : unsigned; point_radius : double = 5 ); + + procedure line_color_(c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor simple_polygon_vertex_source.Construct; +begin + m_polygon :=polygon; + m_num_points:=np; + m_vertex :=0; + m_roundoff :=roundoff; + m_close :=close; + +end; + +{ CLOSE_ } +procedure simple_polygon_vertex_source.close_; +begin + m_close:=f; + +end; + +{ _CLOSE } +function simple_polygon_vertex_source._close; +begin + result:=m_close; + +end; + +{ REWIND } +procedure simple_polygon_vertex_source.rewind; +begin + m_vertex:=0; + +end; + +{ VERTEX } +function simple_polygon_vertex_source.vertex; +begin + if m_vertex > m_num_points then + begin + result:=path_cmd_stop; + + exit; + + end; + + if m_vertex = m_num_points then + begin + inc(m_vertex ); + + if m_close then + result:=path_cmd_end_poly or path_flags_close + else + result:=path_cmd_end_poly or 0; + + exit; + + end; + + x^:=double_ptr(ptrcomp(m_polygon ) + (m_vertex * 2 ) * sizeof(double ) )^; + y^:=double_ptr(ptrcomp(m_polygon ) + (m_vertex * 2 + 1 ) * sizeof(double ) )^; + + if m_roundoff then + begin + x^:=Floor(x^ ) + 0.5; + y^:=Floor(y^ ) + 0.5; + + end; + + inc(m_vertex ); + + if m_vertex = 1 then + result:=path_cmd_move_to + else + result:=path_cmd_line_to; + +end; + +{ CONSTRUCT } +constructor polygon_ctrl_impl.Construct; +begin + inherited Construct(0 ,0 ,1 ,1 ,false ); + + agg_getmem(pointer(m_polygon ) ,np * 2 * sizeof(double ) ); + + m_num_points:=np; + + m_node:=-1; + m_edge:=-1; + + m_vs.Construct (m_polygon ,m_num_points ,false ); + m_stroke.Construct(@m_vs ); + m_ellipse.Construct; + + m_point_radius:=point_radius; + + m_status:=0; + + m_dx:=0.0; + m_dy:=0.0; + + m_in_polygon_check:=false; + + m_stroke.width_(1.0 ); + +end; + +{ DESTRUCT } +destructor polygon_ctrl_impl.Destruct; +begin + agg_freemem(pointer(m_polygon ) ,m_num_points * 2 * sizeof(double ) ); + + m_stroke.Destruct; + +end; + +{ _NUM_POINTS } +function polygon_ctrl_impl._num_points; +begin + result:=m_num_points; + +end; + +{ _XN } +function polygon_ctrl_impl._xn; +begin + result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 ) * sizeof(double ) )^; + +end; + +{ _YN } +function polygon_ctrl_impl._yn; +begin + result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 + 1 ) * sizeof(double ) )^; + +end; + +{ XN_PTR } +function polygon_ctrl_impl.xn_ptr; +begin + result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 ) * sizeof(double ) ); + +end; + +{ YN_PTR } +function polygon_ctrl_impl.yn_ptr; +begin + result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 + 1 ) * sizeof(double ) ); + +end; + +{ _POLYGON } +function polygon_ctrl_impl._polygon; +begin + result:=m_polygon; + +end; + +{ LINE_WIDTH_ } +procedure polygon_ctrl_impl.line_width_; +begin + m_stroke.width_(w ); + +end; + +{ _LINE_WIDTH } +function polygon_ctrl_impl._line_width; +begin + result:=m_stroke._width; + +end; + +{ POINT_RADIUS_ } +procedure polygon_ctrl_impl.point_radius_; +begin + m_point_radius:=r; + +end; + +{ _POINT_RADIUS } +function polygon_ctrl_impl._point_radius; +begin + result:=m_point_radius; + +end; + +{ IN_POLYGON_CHECK_ } +procedure polygon_ctrl_impl.in_polygon_check_; +begin + m_in_polygon_check:=f; + +end; + +{ _IN_POLYGON_CHECK } +function polygon_ctrl_impl._in_polygon_check; +begin + result:=m_in_polygon_check; + +end; + +{ CLOSE_ } +procedure polygon_ctrl_impl.close_; +begin + m_vs.close_(f ); + +end; + +{ _CLOSE } +function polygon_ctrl_impl._close; +begin + result:=m_vs._close; + +end; + +{ NUM_PATHS } +function polygon_ctrl_impl.num_paths; +begin + result:=1; + +end; + +{ REWIND } +procedure polygon_ctrl_impl.rewind; +begin + m_status:=0; + + m_stroke.rewind(0 ); + +end; + +{ VERTEX } +function polygon_ctrl_impl.vertex; +var + cmd : unsigned; + r : double; + +begin + cmd:=path_cmd_stop; + r :=m_point_radius; + + if m_status = 0 then + begin + cmd:=m_stroke.vertex(x ,y ); + + if not is_stop(cmd ) then + begin + transform_xy(x ,y ); + + result:=cmd; + + exit; + + end; + + if (m_node >= 0 ) and + (m_node = m_status ) then + r:=r * 1.2; + + m_ellipse.init(_xn(m_status ) ,_yn(m_status ) ,r ,r ,32 ); + + inc(m_status ); + + end; + + cmd:=m_ellipse.vertex(x ,y ); + + if not is_stop(cmd ) then + begin + transform_xy(x ,y ); + + result:=cmd; + + exit; + + end; + + if m_status >= m_num_points then + begin + result:=path_cmd_stop; + + exit; + + end; + + if (m_node >= 0 ) and + (m_node = m_status ) then + r:=r * 1.2; + + m_ellipse.init(_xn(m_status ) ,_yn(m_status ) ,r ,r ,32 ); + + inc(m_status ); + + cmd:=m_ellipse.vertex(x ,y ); + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ IN_RECT } +function polygon_ctrl_impl.in_rect; +begin + result:=false; + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function polygon_ctrl_impl.on_mouse_button_down; +var + i : unsigned; + ret : boolean; + +begin + ret:=false; + + m_node:=-1; + m_edge:=-1; + + inverse_transform_xy(@x ,@y ); + + for i:=0 to m_num_points - 1 do + if Sqrt((x - _xn(i ) ) * (x - _xn(i ) ) + (y - _yn(i ) ) * (y - _yn(i ) ) ) < m_point_radius then + begin + m_dx :=x - _xn(i ); + m_dy :=y - _yn(i ); + m_node:=i; + ret :=true; + + break; + + end; + + if not ret then + for i:=0 to m_num_points - 1 do + if check_edge(i ,x ,y ) then + begin + m_dx :=x; + m_dy :=y; + m_edge:=i; + ret :=true; + + break; + + end; + + if not ret then + if point_in_polygon(x ,y ) then + begin + m_dx :=x; + m_dy :=y; + m_node:=m_num_points; + ret :=true; + + end; + + result:=ret; + +end; + +{ ON_MOUSE_BUTTON_UP } +function polygon_ctrl_impl.on_mouse_button_up; +var + ret : boolean; + +begin + ret :=(m_node >= 0 ) or (m_edge >= 0 ); + m_node:=-1; + m_edge:=-1; + result:=ret; + +end; + +{ ON_MOUSE_MOVE } +function polygon_ctrl_impl.on_mouse_move; +var + ret : boolean; + + i ,n1 ,n2 : unsigned; + + dx ,dy : double; + +begin + ret:=false; + + inverse_transform_xy(@x ,@y ); + + if m_node = m_num_points then + begin + dx:=x - m_dx; + dy:=y - m_dy; + + for i:=0 to m_num_points - 1 do + begin + xn_ptr(i )^:=_xn(i ) + dx; + yn_ptr(i )^:=_yn(i ) + dy; + + end; + + m_dx:=x; + m_dy:=y; + ret :=true; + + end + else + if m_edge >= 0 then + begin + n1:=m_edge; + n2:=(n1 + m_num_points - 1 ) mod m_num_points; + dx:=x - m_dx; + dy:=y - m_dy; + + xn_ptr(n1 )^:=_xn(n1 ) + dx; + yn_ptr(n1 )^:=_yn(n1 ) + dy; + xn_ptr(n2 )^:=_xn(n2 ) + dx; + yn_ptr(n2 )^:=_yn(n2 ) + dy; + + m_dx:=x; + m_dy:=y; + ret :=true; + + end + else + if m_node >= 0 then + begin + xn_ptr(m_node )^:=x - m_dx; + yn_ptr(m_node )^:=y - m_dy; + + ret:=true; + + end; + + result:=ret; + +end; + +{ ON_ARROW_KEYS } +function polygon_ctrl_impl.on_arrow_keys; +begin + result:=false; + +end; + +{ CHECK_EDGE } +function polygon_ctrl_impl.check_edge; +var + ret : boolean; + + n1 ,n2 : unsigned; + + x1 ,y1 ,x2 ,y2 ,dx ,dy ,x3 ,y3 ,x4 ,y4 ,den ,u1 ,xi ,yi : double; + +begin + ret:=false; + + n1:=i; + n2:=(i + m_num_points - 1 ) mod m_num_points; + x1:=_xn(n1 ); + y1:=_yn(n1 ); + x2:=_xn(n2 ); + y2:=_yn(n2 ); + + dx:=x2 - x1; + dy:=y2 - y1; + + if Sqrt(dx * dx + dy * dy ) > 0.0000001 then + begin + x3:=x; + y3:=y; + x4:=x3 - dy; + y4:=y3 + dx; + + den:=(y4 - y3 ) * (x2 - x1 ) - (x4 - x3 ) * (y2 - y1 ); + u1 :=((x4 - x3 ) * (y1 - y3 ) - (y4 - y3 ) * (x1 - x3 ) ) / den; + + xi:=x1 + u1 * (x2 - x1 ); + yi:=y1 + u1 * (y2 - y1 ); + + dx:=xi - x; + dy:=yi - y; + + if (u1 > 0.0 ) and + (u1 < 1.0 ) and + (Sqrt(dx * dx + dy * dy ) <= m_point_radius ) then + ret:=true; + + end; + + result:=ret; + +end; + +{ POINT_IN_POLYGON } +//======= Crossings Multiply algorithm of InsideTest ======================== +// +// By Eric Haines, 3D/Eye Inc, erich@eye.com +// +// This version is usually somewhat faster than the original published in +// Graphics Gems IV; by turning the division for testing the X axis crossing +// into a tricky multiplication test this part of the test became faster, +// which had the additional effect of making the test for "both to left or +// both to right" a bit slower for triangles than simply computing the +// intersection each time. The main increase is in triangle testing speed, +// which was about 15% faster; all other polygon complexities were pretty much +// the same as before. On machines where division is very expensive (not the +// case on the HP 9000 series on which I tested) this test should be much +// faster overall than the old code. Your mileage may (in fact, will) vary, +// depending on the machine and the test data, but in general I believe this +// code is both shorter and faster. This test was inspired by unpublished +// Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. +// Related work by Samosky is in: +// +// Samosky, Joseph, "SectionView: A system for interactively specifying and +// visualizing sections through three-dimensional medical image data", +// M.S. Thesis, Department of Electrical Engineering and Computer Science, +// Massachusetts Institute of Technology, 1993. +// +// Shoot a test ray along +X axis. The strategy is to compare vertex Y values +// to the testing point's Y and quickly discard edges which are entirely to one +// side of the test ray. Note that CONVEX and WINDING code can be added as +// for the CrossingsTest() code; it is left out here for clarity. +// +// Input 2D polygon _pgon_ with _numverts_ number of vertices and test point +// _point_, returns 1 if inside, 0 if outside. +function polygon_ctrl_impl.point_in_polygon; +var + j ,k : unsigned; + + yflag0 ,yflag1 ,inside_flag : int; + + vtx0 ,vty0 ,vtx1 ,vty1 : double; + +begin + if m_num_points < 3 then + begin + result:=false; + + exit; + + end; + + if not m_in_polygon_check then + begin + result:=false; + + exit; + + end; + + vtx0:=_xn(m_num_points - 1 ); + vty0:=_yn(m_num_points - 1 ); + +// get test bit for above/below X axis + yflag0:=int(vty0 >= y); + + vtx1:=_xn(0 ); + vty1:=_yn(0 ); + + inside_flag:=0; + + for j:=1 to m_num_points do + begin + yflag1:=int(vty1 >= y ); + + // Check if endpoints straddle (are on opposite sides) of X axis + // (i.e. the Y's differ); if so, +X ray could intersect this edge. + // The old test also checked whether the endpoints are both to the + // right or to the left of the test point. However, given the faster + // intersection point computation used below, this test was found to + // be a break-even proposition for most polygons and a loser for + // triangles (where 50% or more of the edges which survive this test + // will cross quadrants and so have to have the X intersection computed + // anyway). I credit Joseph Samosky with inspiring me to try dropping + // the "both left or both right" part of my code. + if yflag0 <> yflag1 then + // Check intersection of pgon segment with +X ray. + // Note if >= point's X; if so, the ray hits it. + // The division operation is avoided for the ">=" test by checking + // the sign of the first vertex wrto the test point; idea inspired + // by Joseph Samosky's and Mark Haigh-Hutchinson's different + // polygon inclusion tests. + if int((vty1 - y ) * (vtx0 - vtx1 ) >= + (vtx1 - x ) * (vty0 - vty1 ) ) = yflag1 then + inside_flag:=inside_flag xor 1; + + // Move to the next pair of vertices, retaining info as possible. + yflag0:=yflag1; + vtx0 :=vtx1; + vty0 :=vty1; + + if j >= m_num_points then + k:=j - m_num_points + else + k:=j; + + vtx1:=_xn(k ); + vty1:=_yn(k ); + + end; + + result:=inside_flag <> 0; + +end; + +{ CONSTRUCT } +constructor polygon_ctrl.Construct; +begin + inherited Construct(np ,point_radius ); + + m_color.ConstrDbl(0.0 ,0.0 ,0.0 ); + +end; + +{ LINE_COLOR_ } +procedure polygon_ctrl.line_color_; +begin + m_color:=c^; + +end; + +{ _COLOR } +function polygon_ctrl._color; +begin + result:=@m_color; + +end; + +END. + diff --git a/src/corelib/render/software/ctrl/agg_rbox_ctrl.pas b/src/corelib/render/software/ctrl/agg_rbox_ctrl.pas index 4b445138..08fd3e63 100644 --- a/src/corelib/render/software/ctrl/agg_rbox_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_rbox_ctrl.pas @@ -1,621 +1,621 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 19.01.2006-Milano: Unit port establishment
-//
-{ agg_rbox_ctrl.pas }
-unit
- agg_rbox_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- SysUtils ,
- agg_basics ,
- agg_ctrl ,
- agg_conv_stroke ,
- agg_gsv_text ,
- agg_color ,
- agg_ellipse ,
- agg_math ,
- agg_math_stroke ;
-
-{ TYPES DEFINITION }
-type
- rbox_ctrl_impl = object(ctrl )
- m_border_width ,
- m_border_extra ,
- m_text_thickness ,
- m_text_height ,
- m_text_width : double;
-
- m_items : array[0..31 ] of char_ptr;
- m_sizes : array[0..31 ] of int8u;
-
- m_num_items : unsigned;
- m_cur_item : int;
-
- m_xs1 ,
- m_ys1 ,
- m_xs2 ,
- m_ys2 ,
- m_dy : double;
-
- m_vx ,
- m_vy : array[0..31 ] of double;
-
- m_draw_item : unsigned;
-
- m_ellipse : ellipse;
- m_ellipse_poly : conv_stroke;
- m_text : gsv_text;
- m_text_poly : conv_stroke;
-
- m_idx ,
- m_vertex : unsigned;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y_ : boolean = false );
- destructor Destruct; virtual;
-
- procedure border_width_ (t : double; extra : double = 0.0 );
- procedure text_thickness_(t : double );
- procedure text_size_ (h : double; w : double = 0.0 );
-
- procedure add_item (text : PChar );
- function _cur_item : int;
- procedure cur_item_(i : int );
-
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- // Vertex source interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- procedure calc_rbox;
-
- end;
-
- rbox_ctrl_ptr = ^rbox_ctrl;
- rbox_ctrl = object(rbox_ctrl_impl )
- m_background_color ,
- m_border_color ,
- m_text_color ,
- m_inactive_color ,
- m_active_color : aggclr;
-
- m_colors : array[0..4 ] of aggclr_ptr;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y_ : boolean = false );
-
- procedure background_color_(c : aggclr_ptr );
- procedure border_color_ (c : aggclr_ptr );
- procedure text_color_ (c : aggclr_ptr );
- procedure inactive_color_ (c : aggclr_ptr );
- procedure active_color_ (c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor rbox_ctrl_impl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y_ );
-
- m_ellipse.Construct;
- m_text.Construct;
-
- m_ellipse_poly.Construct(@m_ellipse );
- m_text_poly.Construct (@m_text );
-
- m_border_width :=1.0;
- m_border_extra :=0.0;
- m_text_thickness:=1.5;
- m_text_height :=9.0;
- m_text_width :=0.0;
-
- m_num_items:=0;
- m_cur_item :=-1;
-
- m_idx :=0;
- m_vertex:=0;
-
- calc_rbox;
-
-end;
-
-{ DESTRUCT }
-destructor rbox_ctrl_impl.Destruct;
-begin
- m_ellipse_poly.Destruct;
- m_text_poly.Destruct;
-
- m_text.Destruct;
-
- while m_num_items > 0 do
- begin
- agg_freemem(p32(m_items[m_num_items - 1 ] ).ptr ,m_sizes[m_num_items - 1 ] );
-
- dec(m_num_items );
-
- end;
-
-end;
-
-{ BORDER_WIDTH_ }
-procedure rbox_ctrl_impl.border_width_;
-begin
- m_border_width:=t;
- m_border_extra:=extra;
-
- calc_rbox;
-
-end;
-
-{ TEXT_THICKNESS_ }
-procedure rbox_ctrl_impl.text_thickness_;
-begin
- m_text_thickness:=t;
-
-end;
-
-{ TEXT_SIZE_ }
-procedure rbox_ctrl_impl.text_size_;
-begin
- m_text_width :=w;
- m_text_height:=h;
-
-end;
-
-{ ADD_ITEM }
-procedure rbox_ctrl_impl.add_item;
-begin
- if m_num_items < 32 then
- begin
- if StrLen(text ) > 255 then
- m_sizes[m_num_items ]:=255
- else
- m_sizes[m_num_items ]:=StrLen(text ) + 1;
-
- agg_getmem(p32(m_items[m_num_items ] ).ptr ,m_sizes[m_num_items ] );
-
- fillchar(p32(m_items[m_num_items ] ).ptr^ ,m_sizes[m_num_items ] ,0 );
- move (text^ ,p32(m_items[m_num_items ] ).ptr^ ,m_sizes[m_num_items ] - 1 );
-
- inc(m_num_items );
-
- end;
-
-end;
-
-{ _CUR_ITEM }
-function rbox_ctrl_impl._cur_item;
-begin
- result:=m_cur_item;
-
-end;
-
-{ CUR_ITEM_ }
-procedure rbox_ctrl_impl.cur_item_;
-begin
- m_cur_item:=i;
-
-end;
-
-{ IN_RECT }
-function rbox_ctrl_impl.in_rect;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=
- (x >= m_x1 ) and
- (x <= m_x2 ) and
- (y >= m_y1 ) and
- (y <= m_y2 );
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function rbox_ctrl_impl.on_mouse_button_down;
-var
- i : unsigned;
-
- xp ,yp : double;
-
-begin
- inverse_transform_xy(@x ,@y );
-
- for i:=0 to m_num_items - 1 do
- begin
- xp:=m_xs1 + m_dy / 1.3;
- yp:=m_ys1 + m_dy * i + m_dy / 1.3;
-
- if calc_distance(x ,y ,xp ,yp ) <= m_text_height / 1.5 then
- begin
- m_cur_item:=i;
-
- result:=true;
-
- exit;
-
- end;
-
- end;
-
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function rbox_ctrl_impl.on_mouse_button_up;
-begin
- result:=false;
-
-end;
-
-{ ON_MOUSE_MOVE }
-function rbox_ctrl_impl.on_mouse_move;
-begin
- result:=false;
-
-end;
-
-{ ON_ARROW_KEYS }
-function rbox_ctrl_impl.on_arrow_keys;
-begin
- if m_cur_item >= 0 then
- begin
- if up or right then
- begin
- inc(m_cur_item );
-
- if m_cur_item >= m_num_items then
- m_cur_item:=0;
-
- result:=true;
-
- exit;
-
- end;
-
- if down or left then
- begin
- dec(m_cur_item );
-
- if m_cur_item < 0 then
- m_cur_item:=m_num_items - 1;
-
- result:=true;
-
- exit;
-
- end;
-
- end;
-
- result:=false;
-
-end;
-
-{ NUM_PATHS }
-function rbox_ctrl_impl.num_paths;
-begin
- result:=5;
-
-end;
-
-{ REWIND }
-procedure rbox_ctrl_impl.rewind;
-begin
- m_idx:=path_id;
- m_dy :=m_text_height * 2.0;
-
- m_draw_item:=0;
-
- case path_id of
- 0 : // Background
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1 - m_border_extra;
- m_vy[0 ]:=m_y1 - m_border_extra;
- m_vx[1 ]:=m_x2 + m_border_extra;
- m_vy[1 ]:=m_y1 - m_border_extra;
- m_vx[2 ]:=m_x2 + m_border_extra;
- m_vy[2 ]:=m_y2 + m_border_extra;
- m_vx[3 ]:=m_x1 - m_border_extra;
- m_vy[3 ]:=m_y2 + m_border_extra;
-
- end;
-
- 1 : // Border
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1;
- m_vy[0 ]:=m_y1;
- m_vx[1 ]:=m_x2;
- m_vy[1 ]:=m_y1;
- m_vx[2 ]:=m_x2;
- m_vy[2 ]:=m_y2;
- m_vx[3 ]:=m_x1;
- m_vy[3 ]:=m_y2;
- m_vx[4 ]:=m_x1 + m_border_width;
- m_vy[4 ]:=m_y1 + m_border_width;
- m_vx[5 ]:=m_x1 + m_border_width;
- m_vy[5 ]:=m_y2 - m_border_width;
- m_vx[6 ]:=m_x2 - m_border_width;
- m_vy[6 ]:=m_y2 - m_border_width;
- m_vx[7 ]:=m_x2 - m_border_width;
- m_vy[7 ]:=m_y1 + m_border_width;
-
- end;
-
- 2 : // Text
- begin
- m_text.text_ (pointer(m_items[0 ] ) );
- m_text.start_point_(m_xs1 + m_dy * 1.5 ,m_ys1 + m_dy / 2.0 );
- m_text.size_ (m_text_height ,m_text_width );
-
- m_text_poly.width_ (m_text_thickness);
- m_text_poly.line_join_(round_join );
- m_text_poly.line_cap_ (round_cap );
-
- m_text_poly.rewind(0 );
-
- end;
-
- 3 : // Inactive items
- begin
- m_ellipse.init(
- m_xs1 + m_dy / 1.3 ,
- m_ys1 + m_dy / 1.3 ,
- m_text_height / 1.5 ,
- m_text_height / 1.5 ,32 );
-
- m_ellipse_poly.width_(m_text_thickness );
- m_ellipse_poly.rewind(0 );
-
- end;
-
- 4 : // Active Item
- if m_cur_item >= 0 then
- begin
- m_ellipse.init(
- m_xs1 + m_dy / 1.3 ,
- m_ys1 + m_dy * m_cur_item + m_dy / 1.3 ,
- m_text_height / 2.0 ,
- m_text_height / 2.0 ,32 );
-
- m_ellipse.rewind(0 );
-
- end;
-
- end;
-
-end;
-
-{ VERTEX }
-function rbox_ctrl_impl.vertex;
-var
- cmd : unsigned;
-
-label
- _Esc ;
-
-begin
- cmd:=path_cmd_line_to;
-
- case m_idx of
- 0 :
- begin
- if m_vertex = 0 then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 4 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 1 :
- begin
- if (m_vertex = 0 ) or
- (m_vertex = 4 ) then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 8 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 2 :
- begin
- cmd:=m_text_poly.vertex(x ,y );
-
- if is_stop(cmd ) then
- begin
- inc(m_draw_item );
-
- if m_draw_item >= m_num_items then
- goto _Esc
- else
- begin
- m_text.text_ (pointer(m_items[m_draw_item ] ) );
- m_text.start_point_(
- m_xs1 + m_dy * 1.5 ,
- m_ys1 + m_dy * (m_draw_item + 1 ) - m_dy / 2.0 );
-
- m_text_poly.rewind(0 );
-
- cmd:=m_text_poly.vertex(x ,y );
-
- end;
-
- end;
-
- end;
-
- 3 :
- begin
- cmd:=m_ellipse_poly.vertex(x ,y );
-
- if is_stop(cmd ) then
- begin
- inc(m_draw_item );
-
- if m_draw_item >= m_num_items then
- goto _Esc
- else
- begin
- m_ellipse.init(
- m_xs1 + m_dy / 1.3 ,
- m_ys1 + m_dy * m_draw_item + m_dy / 1.3 ,
- m_text_height / 1.5 ,
- m_text_height / 1.5 ,32 );
-
- m_ellipse_poly.rewind(0 );
-
- cmd:=m_ellipse_poly.vertex(x ,y );
-
- end;
-
- end;
-
- end;
-
- 4 :
- if m_cur_item >= 0 then
- cmd:=m_ellipse.vertex(x ,y )
- else
- cmd:=path_cmd_stop;
-
- else
- cmd:=path_cmd_stop;
-
- end;
-
-_Esc:
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ CALC_RBOX }
-procedure rbox_ctrl_impl.calc_rbox;
-begin
- m_xs1:=m_x1 + m_border_width;
- m_ys1:=m_y1 + m_border_width;
- m_xs2:=m_x2 - m_border_width;
- m_ys2:=m_y2 - m_border_width;
-
-end;
-
-{ CONSTRUCT }
-constructor rbox_ctrl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y_ );
-
- m_background_color.ConstrDbl(1.0 ,1.0 ,0.9 );
- m_border_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_text_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_inactive_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_active_color.ConstrDbl (0.4 ,0.0 ,0.0 );
-
- m_colors[0 ]:=@m_background_color;
- m_colors[1 ]:=@m_border_color;
- m_colors[2 ]:=@m_text_color;
- m_colors[3 ]:=@m_inactive_color;
- m_colors[4 ]:=@m_active_color;
-
-end;
-
-{ BACKGROUND_COLOR_ }
-procedure rbox_ctrl.background_color_;
-begin
- m_background_color:=c^;
-
-end;
-
-{ BORDER_COLOR_ }
-procedure rbox_ctrl.border_color_;
-begin
- m_border_color:=c^;
-
-end;
-
-{ TEXT_COLOR_ }
-procedure rbox_ctrl.text_color_;
-begin
- m_text_color:=c^;
-
-end;
-
-{ INACTIVE_COLOR_ }
-procedure rbox_ctrl.inactive_color_;
-begin
- m_inactive_color:=c^;
-
-end;
-
-{ ACTIVE_COLOR_ }
-procedure rbox_ctrl.active_color_;
-begin
- m_active_color:=c^;
-
-end;
-
-{ _COLOR }
-function rbox_ctrl._color;
-begin
- result:=m_colors[i ];
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 19.01.2006-Milano: Unit port establishment +// +{ agg_rbox_ctrl.pas } +unit + agg_rbox_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + SysUtils , + agg_basics , + agg_ctrl , + agg_conv_stroke , + agg_gsv_text , + agg_color , + agg_ellipse , + agg_math , + agg_math_stroke ; + +{ TYPES DEFINITION } +type + rbox_ctrl_impl = object(ctrl ) + m_border_width , + m_border_extra , + m_text_thickness , + m_text_height , + m_text_width : double; + + m_items : array[0..31 ] of char_ptr; + m_sizes : array[0..31 ] of int8u; + + m_num_items : unsigned; + m_cur_item : int; + + m_xs1 , + m_ys1 , + m_xs2 , + m_ys2 , + m_dy : double; + + m_vx , + m_vy : array[0..31 ] of double; + + m_draw_item : unsigned; + + m_ellipse : ellipse; + m_ellipse_poly : conv_stroke; + m_text : gsv_text; + m_text_poly : conv_stroke; + + m_idx , + m_vertex : unsigned; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y_ : boolean = false ); + destructor Destruct; virtual; + + procedure border_width_ (t : double; extra : double = 0.0 ); + procedure text_thickness_(t : double ); + procedure text_size_ (h : double; w : double = 0.0 ); + + procedure add_item (text : PChar ); + function _cur_item : int; + procedure cur_item_(i : int ); + + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Vertex source interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + procedure calc_rbox; + + end; + + rbox_ctrl_ptr = ^rbox_ctrl; + rbox_ctrl = object(rbox_ctrl_impl ) + m_background_color , + m_border_color , + m_text_color , + m_inactive_color , + m_active_color : aggclr; + + m_colors : array[0..4 ] of aggclr_ptr; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y_ : boolean = false ); + + procedure background_color_(c : aggclr_ptr ); + procedure border_color_ (c : aggclr_ptr ); + procedure text_color_ (c : aggclr_ptr ); + procedure inactive_color_ (c : aggclr_ptr ); + procedure active_color_ (c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor rbox_ctrl_impl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y_ ); + + m_ellipse.Construct; + m_text.Construct; + + m_ellipse_poly.Construct(@m_ellipse ); + m_text_poly.Construct (@m_text ); + + m_border_width :=1.0; + m_border_extra :=0.0; + m_text_thickness:=1.5; + m_text_height :=9.0; + m_text_width :=0.0; + + m_num_items:=0; + m_cur_item :=-1; + + m_idx :=0; + m_vertex:=0; + + calc_rbox; + +end; + +{ DESTRUCT } +destructor rbox_ctrl_impl.Destruct; +begin + m_ellipse_poly.Destruct; + m_text_poly.Destruct; + + m_text.Destruct; + + while m_num_items > 0 do + begin + agg_freemem(p32(m_items[m_num_items - 1 ] ).ptr ,m_sizes[m_num_items - 1 ] ); + + dec(m_num_items ); + + end; + +end; + +{ BORDER_WIDTH_ } +procedure rbox_ctrl_impl.border_width_; +begin + m_border_width:=t; + m_border_extra:=extra; + + calc_rbox; + +end; + +{ TEXT_THICKNESS_ } +procedure rbox_ctrl_impl.text_thickness_; +begin + m_text_thickness:=t; + +end; + +{ TEXT_SIZE_ } +procedure rbox_ctrl_impl.text_size_; +begin + m_text_width :=w; + m_text_height:=h; + +end; + +{ ADD_ITEM } +procedure rbox_ctrl_impl.add_item; +begin + if m_num_items < 32 then + begin + if StrLen(text ) > 255 then + m_sizes[m_num_items ]:=255 + else + m_sizes[m_num_items ]:=StrLen(text ) + 1; + + agg_getmem(p32(m_items[m_num_items ] ).ptr ,m_sizes[m_num_items ] ); + + fillchar(p32(m_items[m_num_items ] ).ptr^ ,m_sizes[m_num_items ] ,0 ); + move (text^ ,p32(m_items[m_num_items ] ).ptr^ ,m_sizes[m_num_items ] - 1 ); + + inc(m_num_items ); + + end; + +end; + +{ _CUR_ITEM } +function rbox_ctrl_impl._cur_item; +begin + result:=m_cur_item; + +end; + +{ CUR_ITEM_ } +procedure rbox_ctrl_impl.cur_item_; +begin + m_cur_item:=i; + +end; + +{ IN_RECT } +function rbox_ctrl_impl.in_rect; +begin + inverse_transform_xy(@x ,@y ); + + result:= + (x >= m_x1 ) and + (x <= m_x2 ) and + (y >= m_y1 ) and + (y <= m_y2 ); + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function rbox_ctrl_impl.on_mouse_button_down; +var + i : unsigned; + + xp ,yp : double; + +begin + inverse_transform_xy(@x ,@y ); + + for i:=0 to m_num_items - 1 do + begin + xp:=m_xs1 + m_dy / 1.3; + yp:=m_ys1 + m_dy * i + m_dy / 1.3; + + if calc_distance(x ,y ,xp ,yp ) <= m_text_height / 1.5 then + begin + m_cur_item:=i; + + result:=true; + + exit; + + end; + + end; + + result:=false; + +end; + +{ ON_MOUSE_BUTTON_UP } +function rbox_ctrl_impl.on_mouse_button_up; +begin + result:=false; + +end; + +{ ON_MOUSE_MOVE } +function rbox_ctrl_impl.on_mouse_move; +begin + result:=false; + +end; + +{ ON_ARROW_KEYS } +function rbox_ctrl_impl.on_arrow_keys; +begin + if m_cur_item >= 0 then + begin + if up or right then + begin + inc(m_cur_item ); + + if m_cur_item >= m_num_items then + m_cur_item:=0; + + result:=true; + + exit; + + end; + + if down or left then + begin + dec(m_cur_item ); + + if m_cur_item < 0 then + m_cur_item:=m_num_items - 1; + + result:=true; + + exit; + + end; + + end; + + result:=false; + +end; + +{ NUM_PATHS } +function rbox_ctrl_impl.num_paths; +begin + result:=5; + +end; + +{ REWIND } +procedure rbox_ctrl_impl.rewind; +begin + m_idx:=path_id; + m_dy :=m_text_height * 2.0; + + m_draw_item:=0; + + case path_id of + 0 : // Background + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1 - m_border_extra; + m_vy[0 ]:=m_y1 - m_border_extra; + m_vx[1 ]:=m_x2 + m_border_extra; + m_vy[1 ]:=m_y1 - m_border_extra; + m_vx[2 ]:=m_x2 + m_border_extra; + m_vy[2 ]:=m_y2 + m_border_extra; + m_vx[3 ]:=m_x1 - m_border_extra; + m_vy[3 ]:=m_y2 + m_border_extra; + + end; + + 1 : // Border + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1; + m_vy[0 ]:=m_y1; + m_vx[1 ]:=m_x2; + m_vy[1 ]:=m_y1; + m_vx[2 ]:=m_x2; + m_vy[2 ]:=m_y2; + m_vx[3 ]:=m_x1; + m_vy[3 ]:=m_y2; + m_vx[4 ]:=m_x1 + m_border_width; + m_vy[4 ]:=m_y1 + m_border_width; + m_vx[5 ]:=m_x1 + m_border_width; + m_vy[5 ]:=m_y2 - m_border_width; + m_vx[6 ]:=m_x2 - m_border_width; + m_vy[6 ]:=m_y2 - m_border_width; + m_vx[7 ]:=m_x2 - m_border_width; + m_vy[7 ]:=m_y1 + m_border_width; + + end; + + 2 : // Text + begin + m_text.text_ (pointer(m_items[0 ] ) ); + m_text.start_point_(m_xs1 + m_dy * 1.5 ,m_ys1 + m_dy / 2.0 ); + m_text.size_ (m_text_height ,m_text_width ); + + m_text_poly.width_ (m_text_thickness); + m_text_poly.line_join_(round_join ); + m_text_poly.line_cap_ (round_cap ); + + m_text_poly.rewind(0 ); + + end; + + 3 : // Inactive items + begin + m_ellipse.init( + m_xs1 + m_dy / 1.3 , + m_ys1 + m_dy / 1.3 , + m_text_height / 1.5 , + m_text_height / 1.5 ,32 ); + + m_ellipse_poly.width_(m_text_thickness ); + m_ellipse_poly.rewind(0 ); + + end; + + 4 : // Active Item + if m_cur_item >= 0 then + begin + m_ellipse.init( + m_xs1 + m_dy / 1.3 , + m_ys1 + m_dy * m_cur_item + m_dy / 1.3 , + m_text_height / 2.0 , + m_text_height / 2.0 ,32 ); + + m_ellipse.rewind(0 ); + + end; + + end; + +end; + +{ VERTEX } +function rbox_ctrl_impl.vertex; +var + cmd : unsigned; + +label + _Esc ; + +begin + cmd:=path_cmd_line_to; + + case m_idx of + 0 : + begin + if m_vertex = 0 then + cmd:=path_cmd_move_to; + + if m_vertex >= 4 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 1 : + begin + if (m_vertex = 0 ) or + (m_vertex = 4 ) then + cmd:=path_cmd_move_to; + + if m_vertex >= 8 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 2 : + begin + cmd:=m_text_poly.vertex(x ,y ); + + if is_stop(cmd ) then + begin + inc(m_draw_item ); + + if m_draw_item >= m_num_items then + goto _Esc + else + begin + m_text.text_ (pointer(m_items[m_draw_item ] ) ); + m_text.start_point_( + m_xs1 + m_dy * 1.5 , + m_ys1 + m_dy * (m_draw_item + 1 ) - m_dy / 2.0 ); + + m_text_poly.rewind(0 ); + + cmd:=m_text_poly.vertex(x ,y ); + + end; + + end; + + end; + + 3 : + begin + cmd:=m_ellipse_poly.vertex(x ,y ); + + if is_stop(cmd ) then + begin + inc(m_draw_item ); + + if m_draw_item >= m_num_items then + goto _Esc + else + begin + m_ellipse.init( + m_xs1 + m_dy / 1.3 , + m_ys1 + m_dy * m_draw_item + m_dy / 1.3 , + m_text_height / 1.5 , + m_text_height / 1.5 ,32 ); + + m_ellipse_poly.rewind(0 ); + + cmd:=m_ellipse_poly.vertex(x ,y ); + + end; + + end; + + end; + + 4 : + if m_cur_item >= 0 then + cmd:=m_ellipse.vertex(x ,y ) + else + cmd:=path_cmd_stop; + + else + cmd:=path_cmd_stop; + + end; + +_Esc: + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ CALC_RBOX } +procedure rbox_ctrl_impl.calc_rbox; +begin + m_xs1:=m_x1 + m_border_width; + m_ys1:=m_y1 + m_border_width; + m_xs2:=m_x2 - m_border_width; + m_ys2:=m_y2 - m_border_width; + +end; + +{ CONSTRUCT } +constructor rbox_ctrl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y_ ); + + m_background_color.ConstrDbl(1.0 ,1.0 ,0.9 ); + m_border_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_text_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_inactive_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_active_color.ConstrDbl (0.4 ,0.0 ,0.0 ); + + m_colors[0 ]:=@m_background_color; + m_colors[1 ]:=@m_border_color; + m_colors[2 ]:=@m_text_color; + m_colors[3 ]:=@m_inactive_color; + m_colors[4 ]:=@m_active_color; + +end; + +{ BACKGROUND_COLOR_ } +procedure rbox_ctrl.background_color_; +begin + m_background_color:=c^; + +end; + +{ BORDER_COLOR_ } +procedure rbox_ctrl.border_color_; +begin + m_border_color:=c^; + +end; + +{ TEXT_COLOR_ } +procedure rbox_ctrl.text_color_; +begin + m_text_color:=c^; + +end; + +{ INACTIVE_COLOR_ } +procedure rbox_ctrl.inactive_color_; +begin + m_inactive_color:=c^; + +end; + +{ ACTIVE_COLOR_ } +procedure rbox_ctrl.active_color_; +begin + m_active_color:=c^; + +end; + +{ _COLOR } +function rbox_ctrl._color; +begin + result:=m_colors[i ]; + +end; + +END. + diff --git a/src/corelib/render/software/ctrl/agg_scale_ctrl.pas b/src/corelib/render/software/ctrl/agg_scale_ctrl.pas index afbfc1c0..e062f56e 100644 --- a/src/corelib/render/software/ctrl/agg_scale_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_scale_ctrl.pas @@ -1,747 +1,747 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 29.01.2006-Milano: Unit port establishment
-//
-{ agg_scale_ctrl.pas }
-unit
- agg_scale_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- agg_basics ,
- agg_ctrl ,
- agg_color ,
- agg_ellipse ,
- agg_math ,
- agg_trans_affine ;
-
-{ TYPES DEFINITION }
-type
- move_e = (move_nothing ,move_value1 ,move_value2 ,move_slider );
-
- scale_ctrl_impl = object(ctrl )
- m_border_thickness ,
- m_border_extra ,
-
- m_value1 ,
- m_value2 ,
- m_min_d ,
-
- m_xs1 ,
- m_ys1 ,
- m_xs2 ,
- m_ys2 ,
- m_pdx ,
- m_pdy : double;
-
- m_move_what : move_e;
- m_vx ,
- m_vy : array[0..31 ] of double;
-
- m_ellipse : ellipse;
-
- m_idx ,
- m_vertex : unsigned;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false );
- destructor Destruct; virtual;
-
- procedure border_thickness_(t : double; extra : double = 0.0 );
-
- procedure resize(x1 ,y1 ,x2 ,y2 : double );
-
- function _min_delta : double;
- procedure min_delta_(d : double );
-
- function _value1 : double;
- procedure value1_(value : double );
-
- function _value2 : double;
- procedure value2_(value : double );
-
- procedure move(d : double );
-
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- // Vertex source interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- // Private
- procedure calc_box;
-
- end;
-
- scale_ctrl = object(scale_ctrl_impl )
- m_background_color ,
- m_border_color ,
- m_pointers_color ,
- m_slider_color : aggclr;
-
- m_colors : array[0..5 ] of aggclr_ptr;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false );
-
- procedure background_color_(c : aggclr_ptr );
- procedure border_color_ (c : aggclr_ptr );
- procedure pointers_color_ (c : aggclr_ptr );
- procedure slider_color_ (c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor scale_ctrl_impl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y );
-
- m_border_thickness:=1.0;
-
- if Abs(x2 - x1 ) > Abs(y2 - y1 ) then
- m_border_extra:=(y2 - y1 ) / 2
- else
- m_border_extra:=(x2 - x1 ) / 2;
-
- m_pdx:=0.0;
- m_pdy:=0.0;
-
- m_move_what:=move_nothing;
-
- m_value1:=0.3;
- m_value2:=0.7;
- m_min_d :=0.01;
-
- m_ellipse.Construct;
-
- calc_box;
-
-end;
-
-{ DESTRUCT }
-destructor scale_ctrl_impl.destruct;
-begin
-end;
-
-{ BORDER_THICKNESS_ }
-procedure scale_ctrl_impl.border_thickness_;
-begin
- m_border_thickness:=t;
- m_border_extra :=extra;
-
- calc_box;
-
-end;
-
-{ RESIZE }
-procedure scale_ctrl_impl.resize;
-begin
- m_x1:=x1;
- m_y1:=y1;
- m_x2:=x2;
- m_y2:=y2;
-
- calc_box;
-
- if Abs(x2 - x1 ) > Abs(y2 - y1 ) then
- m_border_extra:=(y2 - y1 ) / 2
- else
- m_border_extra:=(x2 - x1 ) / 2;
-
-end;
-
-{ _MIN_DELTA }
-function scale_ctrl_impl._min_delta;
-begin
- result:=m_min_d;
-
-end;
-
-{ MIN_DELTA_ }
-procedure scale_ctrl_impl.min_delta_;
-begin
- m_min_d:=d;
-
-end;
-
-{ _VALUE1 }
-function scale_ctrl_impl._value1;
-begin
- result:=m_value1;
-
-end;
-
-{ VALUE1_ }
-procedure scale_ctrl_impl.value1_;
-begin
- if value < 0.0 then
- value:=0.0;
-
- if value > 1.0 then
- value:=1.0;
-
- if m_value2 - value < m_min_d then
- value:=m_value2 - m_min_d;
-
- m_value1:=value;
-
-end;
-
-{ _VALUE2 }
-function scale_ctrl_impl._value2;
-begin
- result:=m_value2;
-
-end;
-
-{ VALUE2_ }
-procedure scale_ctrl_impl.value2_;
-begin
- if value < 0.0 then
- value:=0.0;
-
- if value > 1.0 then
- value:=1.0;
-
- if m_value1 + value < m_min_d then
- value:=m_value1 + m_min_d;
-
- m_value2:=value;
-
-end;
-
-{ MOVE }
-procedure scale_ctrl_impl.move;
-begin
- m_value1:=m_value1 + d;
- m_value2:=m_value2 + d;
-
- if m_value1 < 0.0 then
- begin
- m_value2:=m_value2 - m_value1;
- m_value1:=0.0;
-
- end;
-
- if m_value2 > 1.0 then
- begin
- m_value1:=m_value1 - m_value2 - 1.0;
- m_value2:=1.0;
-
- end;
-
-end;
-
-{ IN_RECT }
-function scale_ctrl_impl.in_rect;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=
- (x >= m_x1 ) and
- (x <= m_x2 ) and
- (y >= m_y1 ) and
- (y <= m_y2 );
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function scale_ctrl_impl.on_mouse_button_down;
-var
- xp1 ,xp2 ,ys1 ,ys2 ,xp ,yp : double;
-
-begin
- inverse_transform_xy(@x ,@y );
-
- if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then
- begin
- xp1:=m_xs1 + (m_xs2 - m_xs1 ) * m_value1;
- xp2:=m_xs1 + (m_xs2 - m_xs1 ) * m_value2;
- ys1:=m_y1 - m_border_extra / 2.0;
- ys2:=m_y2 + m_border_extra / 2.0;
- yp :=(m_ys1 + m_ys2 ) / 2.0;
-
- if (x > xp1 ) and
- (y > ys1 ) and
- (x < xp2 ) and
- (y < ys2 ) then
- begin
- m_pdx:=xp1 - x;
-
- m_move_what:=move_slider;
-
- result:=true;
-
- exit;
-
- end;
-
- //if(x < xp1 && calc_distance(x, y, xp1, yp) <= m_y2 - m_y1)
- if calc_distance(x ,y ,xp1 ,yp ) <= m_y2 - m_y1 then
- begin
- m_pdx:=xp1 - x;
-
- m_move_what:=move_value1;
-
- result:=true;
-
- exit;
-
- end;
-
- //if(x > xp2 && calc_distance(x, y, xp2, yp) <= m_y2 - m_y1)
- if calc_distance(x ,y ,xp2 ,yp ) <= m_y2 - m_y1 then
- begin
- m_pdx:=xp2 - x;
-
- m_move_what:=move_value2;
-
- result:=true;
-
- end;
-
- end
- else
- begin
- xp1:=m_x1 - m_border_extra / 2.0;
- xp2:=m_x2 + m_border_extra / 2.0;
- ys1:=m_ys1 + (m_ys2 - m_ys1 ) * m_value1;
- ys2:=m_ys1 + (m_ys2 - m_ys1 ) * m_value2;
- xp :=(m_xs1 + m_xs2 ) / 2.0;
-
- if (x > xp1 ) and
- (y > ys1 ) and
- (x < xp2 ) and
- (y < ys2 ) then
- begin
- m_pdy:=ys1 - y;
-
- m_move_what:=move_slider;
-
- result:=true;
-
- exit;
-
- end;
-
- //if(y < ys1 && calc_distance(x, y, xp, ys1) <= m_x2 - m_x1)
- if calc_distance(x ,y ,xp ,ys1 ) <= m_x2 - m_x1 then
- begin
- m_pdy:=ys1 - y;
-
- m_move_what:=move_value1;
-
- result:=true;
-
- exit;
-
- end;
-
- //if(y > ys2 && calc_distance(x, y, xp, ys2) <= m_x2 - m_x1)
- if calc_distance(x, y, xp, ys2) <= m_x2 - m_x1 then
- begin
- m_pdy:=ys2 - y;
-
- m_move_what:=move_value2;
-
- result:=true;
-
- exit;
-
- end;
-
- end;
-
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function scale_ctrl_impl.on_mouse_button_up;
-begin
- m_move_what:=move_nothing;
-
- result:=false;
-
-end;
-
-{ ON_MOUSE_MOVE }
-function scale_ctrl_impl.on_mouse_move;
-var
- xp ,yp ,dv : double;
-
-begin
- inverse_transform_xy(@x ,@y );
-
- if not button_flag then
- result:=on_mouse_button_up(x ,y )
- else
- begin
- xp:=x + m_pdx;
- yp:=y + m_pdy;
-
- case m_move_what of
- move_value1 :
- begin
- if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then
- m_value1:=(xp - m_xs1 ) / (m_xs2 - m_xs1 )
- else
- m_value1:=(yp - m_ys1 ) / (m_ys2 - m_ys1 );
-
- if m_value1 < 0.0 then
- m_value1:=0.0;
-
- if m_value1 > m_value2 - m_min_d then
- m_value1:=m_value2 - m_min_d;
-
- result:=true;
-
- end;
-
- move_value2 :
- begin
- if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then
- m_value2:=(xp - m_xs1 ) / (m_xs2 - m_xs1 )
- else
- m_value2:=(yp - m_ys1 ) / (m_ys2 - m_ys1 );
-
- if m_value2 > 1.0 then
- m_value2:=1.0;
-
- if m_value2 < m_value1 + m_min_d then
- m_value2:=m_value1 + m_min_d;
-
- result:=true;
-
- end;
-
- move_slider :
- begin
- dv:=m_value2 - m_value1;
-
- if Abs(m_x2 - m_x1 ) > abs(m_y2 - m_y1 ) then
- m_value1:=(xp - m_xs1 ) / (m_xs2 - m_xs1 )
- else
- m_value1:=(yp - m_ys1 ) / (m_ys2 - m_ys1 );
-
- m_value2:=m_value1 + dv;
-
- if m_value1 < 0.0 then
- begin
- dv:=m_value2 - m_value1;
-
- m_value1:=0.0;
- m_value2:=m_value1 + dv;
-
- end;
-
- if m_value2 > 1.0 then
- begin
- dv:=m_value2 - m_value1;
-
- m_value2:=1.0;
- m_value1:=m_value2 - dv;
-
- end;
-
- result:=true;
-
- end;
-
- else
- result:=false;
-
- end;
-
- end;
-
-end;
-
-{ ON_ARROW_KEYS }
-function scale_ctrl_impl.on_arrow_keys;
-begin
- result:=false
-
-end;
-
-{ NUM_PATHS }
-function scale_ctrl_impl.num_paths;
-begin
- result:=5;
-
-end;
-
-{ REWIND }
-procedure scale_ctrl_impl.rewind;
-begin
- m_idx:=path_id;
-
- case path_id of
- 0: // Background
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1 - m_border_extra;
- m_vy[0 ]:=m_y1 - m_border_extra;
- m_vx[1 ]:=m_x2 + m_border_extra;
- m_vy[1 ]:=m_y1 - m_border_extra;
- m_vx[2 ]:=m_x2 + m_border_extra;
- m_vy[2 ]:=m_y2 + m_border_extra;
- m_vx[3 ]:=m_x1 - m_border_extra;
- m_vy[3 ]:=m_y2 + m_border_extra;
-
- end;
-
- 1: // Border
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1;
- m_vy[0 ]:=m_y1;
- m_vx[1 ]:=m_x2;
- m_vy[1 ]:=m_y1;
- m_vx[2 ]:=m_x2;
- m_vy[2 ]:=m_y2;
- m_vx[3 ]:=m_x1;
- m_vy[3 ]:=m_y2;
- m_vx[4 ]:=m_x1 + m_border_thickness;
- m_vy[4 ]:=m_y1 + m_border_thickness;
- m_vx[5 ]:=m_x1 + m_border_thickness;
- m_vy[5 ]:=m_y2 - m_border_thickness;
- m_vx[6 ]:=m_x2 - m_border_thickness;
- m_vy[6 ]:=m_y2 - m_border_thickness;
- m_vx[7 ]:=m_x2 - m_border_thickness;
- m_vy[7 ]:=m_y1 + m_border_thickness;
-
- end;
-
- 2: // pointer1
- begin
- if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then
- m_ellipse.init(
- m_xs1 + (m_xs2 - m_xs1 ) * m_value1 ,
- (m_ys1 + m_ys2 ) / 2.0 ,
- m_y2 - m_y1 ,
- m_y2 - m_y1 ,32 )
- else
- m_ellipse.init(
- (m_xs1 + m_xs2 ) / 2.0,
- m_ys1 + (m_ys2 - m_ys1 ) * m_value1 ,
- m_x2 - m_x1 ,
- m_x2 - m_x1 ,32 );
-
- m_ellipse.rewind(0 );
-
- end;
-
- 3: // pointer2
- begin
- if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then
- m_ellipse.init(
- m_xs1 + (m_xs2 - m_xs1 ) * m_value2 ,
- (m_ys1 + m_ys2 ) / 2.0 ,
- m_y2 - m_y1 ,
- m_y2 - m_y1 ,32 )
- else
- m_ellipse.init(
- (m_xs1 + m_xs2 ) / 2.0 ,
- m_ys1 + (m_ys2 - m_ys1 ) * m_value2 ,
- m_x2 - m_x1 ,
- m_x2 - m_x1 ,32 );
-
- m_ellipse.rewind(0);
-
- end;
-
- 4: // slider
- begin
- m_vertex:=0;
-
- if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then
- begin
- m_vx[0 ]:=m_xs1 + (m_xs2 - m_xs1 ) * m_value1;
- m_vy[0 ]:=m_y1 - m_border_extra / 2.0;
- m_vx[1 ]:=m_xs1 + (m_xs2 - m_xs1 ) * m_value2;
- m_vy[1 ]:=m_vy[0 ];
- m_vx[2 ]:=m_vx[1 ];
- m_vy[2 ]:=m_y2 + m_border_extra / 2.0;
- m_vx[3 ]:=m_vx[0 ];
- m_vy[3 ]:=m_vy[2 ];
-
- end
- else
- begin
- m_vx[0 ]:=m_x1 - m_border_extra / 2.0;
- m_vy[0 ]:=m_ys1 + (m_ys2 - m_ys1 ) * m_value1;
- m_vx[1 ]:=m_vx[0 ];
- m_vy[1 ]:=m_ys1 + (m_ys2 - m_ys1 ) * m_value2;
- m_vx[2 ]:=m_x2 + m_border_extra / 2.0;
- m_vy[2 ]:=m_vy[1 ];
- m_vx[3 ]:=m_vx[2 ];
- m_vy[3 ]:=m_vy[0 ];
-
- end;
-
- end;
-
- end;
-
-end;
-
-{ VERTEX }
-function scale_ctrl_impl.vertex;
-var
- cmd : unsigned;
-
-begin
- cmd:=path_cmd_line_to;
-
- case m_idx of
- 0 ,4 :
- begin
- if m_vertex = 0 then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 4 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 1 :
- begin
- if (m_vertex = 0 ) or
- (m_vertex = 4 ) then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 8 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 2 ,3 :
- cmd:=m_ellipse.vertex(x ,y );
-
- else
- cmd:=path_cmd_stop;
-
- end;
-
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ CALC_BOX }
-procedure scale_ctrl_impl.calc_box;
-begin
- m_xs1:=m_x1 + m_border_thickness;
- m_ys1:=m_y1 + m_border_thickness;
- m_xs2:=m_x2 - m_border_thickness;
- m_ys2:=m_y2 - m_border_thickness;
-
-end;
-
-{ CONSTRUCT }
-constructor scale_ctrl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y );
-
- m_background_color.ConstrDbl(1.0 ,0.9 ,0.8 );
- m_border_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_pointers_color.ConstrDbl (0.8 ,0.0 ,0.0 ,0.8 );
- m_slider_color.ConstrDbl (0.2 ,0.1 ,0.0 ,0.6 );
-
- m_colors[0 ]:=@m_background_color;
- m_colors[1 ]:=@m_border_color;
- m_colors[2 ]:=@m_pointers_color;
- m_colors[3 ]:=@m_pointers_color;
- m_colors[4 ]:=@m_slider_color;
-
-end;
-
-{ BACKGROUND_COLOR_ }
-procedure scale_ctrl.background_color_;
-begin
- m_background_color:=c^;
-
-end;
-
-{ BORDER_COLOR_ }
-procedure scale_ctrl.border_color_;
-begin
- m_border_color:=c^;
-
-end;
-
-{ POINTERS_COLOR_ }
-procedure scale_ctrl.pointers_color_;
-begin
- m_pointers_color:=c^;
-
-end;
-
-{ SLIDER_COLOR_ }
-procedure scale_ctrl.slider_color_;
-begin
- m_slider_color:=c^;
-
-end;
-
-{ _COLOR }
-function scale_ctrl._color;
-begin
- result:=m_colors[i ];
-
-end;
-
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 29.01.2006-Milano: Unit port establishment +// +{ agg_scale_ctrl.pas } +unit + agg_scale_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + agg_basics , + agg_ctrl , + agg_color , + agg_ellipse , + agg_math , + agg_trans_affine ; + +{ TYPES DEFINITION } +type + move_e = (move_nothing ,move_value1 ,move_value2 ,move_slider ); + + scale_ctrl_impl = object(ctrl ) + m_border_thickness , + m_border_extra , + + m_value1 , + m_value2 , + m_min_d , + + m_xs1 , + m_ys1 , + m_xs2 , + m_ys2 , + m_pdx , + m_pdy : double; + + m_move_what : move_e; + m_vx , + m_vy : array[0..31 ] of double; + + m_ellipse : ellipse; + + m_idx , + m_vertex : unsigned; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false ); + destructor Destruct; virtual; + + procedure border_thickness_(t : double; extra : double = 0.0 ); + + procedure resize(x1 ,y1 ,x2 ,y2 : double ); + + function _min_delta : double; + procedure min_delta_(d : double ); + + function _value1 : double; + procedure value1_(value : double ); + + function _value2 : double; + procedure value2_(value : double ); + + procedure move(d : double ); + + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Vertex source interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + // Private + procedure calc_box; + + end; + + scale_ctrl = object(scale_ctrl_impl ) + m_background_color , + m_border_color , + m_pointers_color , + m_slider_color : aggclr; + + m_colors : array[0..5 ] of aggclr_ptr; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false ); + + procedure background_color_(c : aggclr_ptr ); + procedure border_color_ (c : aggclr_ptr ); + procedure pointers_color_ (c : aggclr_ptr ); + procedure slider_color_ (c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor scale_ctrl_impl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y ); + + m_border_thickness:=1.0; + + if Abs(x2 - x1 ) > Abs(y2 - y1 ) then + m_border_extra:=(y2 - y1 ) / 2 + else + m_border_extra:=(x2 - x1 ) / 2; + + m_pdx:=0.0; + m_pdy:=0.0; + + m_move_what:=move_nothing; + + m_value1:=0.3; + m_value2:=0.7; + m_min_d :=0.01; + + m_ellipse.Construct; + + calc_box; + +end; + +{ DESTRUCT } +destructor scale_ctrl_impl.destruct; +begin +end; + +{ BORDER_THICKNESS_ } +procedure scale_ctrl_impl.border_thickness_; +begin + m_border_thickness:=t; + m_border_extra :=extra; + + calc_box; + +end; + +{ RESIZE } +procedure scale_ctrl_impl.resize; +begin + m_x1:=x1; + m_y1:=y1; + m_x2:=x2; + m_y2:=y2; + + calc_box; + + if Abs(x2 - x1 ) > Abs(y2 - y1 ) then + m_border_extra:=(y2 - y1 ) / 2 + else + m_border_extra:=(x2 - x1 ) / 2; + +end; + +{ _MIN_DELTA } +function scale_ctrl_impl._min_delta; +begin + result:=m_min_d; + +end; + +{ MIN_DELTA_ } +procedure scale_ctrl_impl.min_delta_; +begin + m_min_d:=d; + +end; + +{ _VALUE1 } +function scale_ctrl_impl._value1; +begin + result:=m_value1; + +end; + +{ VALUE1_ } +procedure scale_ctrl_impl.value1_; +begin + if value < 0.0 then + value:=0.0; + + if value > 1.0 then + value:=1.0; + + if m_value2 - value < m_min_d then + value:=m_value2 - m_min_d; + + m_value1:=value; + +end; + +{ _VALUE2 } +function scale_ctrl_impl._value2; +begin + result:=m_value2; + +end; + +{ VALUE2_ } +procedure scale_ctrl_impl.value2_; +begin + if value < 0.0 then + value:=0.0; + + if value > 1.0 then + value:=1.0; + + if m_value1 + value < m_min_d then + value:=m_value1 + m_min_d; + + m_value2:=value; + +end; + +{ MOVE } +procedure scale_ctrl_impl.move; +begin + m_value1:=m_value1 + d; + m_value2:=m_value2 + d; + + if m_value1 < 0.0 then + begin + m_value2:=m_value2 - m_value1; + m_value1:=0.0; + + end; + + if m_value2 > 1.0 then + begin + m_value1:=m_value1 - m_value2 - 1.0; + m_value2:=1.0; + + end; + +end; + +{ IN_RECT } +function scale_ctrl_impl.in_rect; +begin + inverse_transform_xy(@x ,@y ); + + result:= + (x >= m_x1 ) and + (x <= m_x2 ) and + (y >= m_y1 ) and + (y <= m_y2 ); + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function scale_ctrl_impl.on_mouse_button_down; +var + xp1 ,xp2 ,ys1 ,ys2 ,xp ,yp : double; + +begin + inverse_transform_xy(@x ,@y ); + + if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then + begin + xp1:=m_xs1 + (m_xs2 - m_xs1 ) * m_value1; + xp2:=m_xs1 + (m_xs2 - m_xs1 ) * m_value2; + ys1:=m_y1 - m_border_extra / 2.0; + ys2:=m_y2 + m_border_extra / 2.0; + yp :=(m_ys1 + m_ys2 ) / 2.0; + + if (x > xp1 ) and + (y > ys1 ) and + (x < xp2 ) and + (y < ys2 ) then + begin + m_pdx:=xp1 - x; + + m_move_what:=move_slider; + + result:=true; + + exit; + + end; + + //if(x < xp1 && calc_distance(x, y, xp1, yp) <= m_y2 - m_y1) + if calc_distance(x ,y ,xp1 ,yp ) <= m_y2 - m_y1 then + begin + m_pdx:=xp1 - x; + + m_move_what:=move_value1; + + result:=true; + + exit; + + end; + + //if(x > xp2 && calc_distance(x, y, xp2, yp) <= m_y2 - m_y1) + if calc_distance(x ,y ,xp2 ,yp ) <= m_y2 - m_y1 then + begin + m_pdx:=xp2 - x; + + m_move_what:=move_value2; + + result:=true; + + end; + + end + else + begin + xp1:=m_x1 - m_border_extra / 2.0; + xp2:=m_x2 + m_border_extra / 2.0; + ys1:=m_ys1 + (m_ys2 - m_ys1 ) * m_value1; + ys2:=m_ys1 + (m_ys2 - m_ys1 ) * m_value2; + xp :=(m_xs1 + m_xs2 ) / 2.0; + + if (x > xp1 ) and + (y > ys1 ) and + (x < xp2 ) and + (y < ys2 ) then + begin + m_pdy:=ys1 - y; + + m_move_what:=move_slider; + + result:=true; + + exit; + + end; + + //if(y < ys1 && calc_distance(x, y, xp, ys1) <= m_x2 - m_x1) + if calc_distance(x ,y ,xp ,ys1 ) <= m_x2 - m_x1 then + begin + m_pdy:=ys1 - y; + + m_move_what:=move_value1; + + result:=true; + + exit; + + end; + + //if(y > ys2 && calc_distance(x, y, xp, ys2) <= m_x2 - m_x1) + if calc_distance(x, y, xp, ys2) <= m_x2 - m_x1 then + begin + m_pdy:=ys2 - y; + + m_move_what:=move_value2; + + result:=true; + + exit; + + end; + + end; + + result:=false; + +end; + +{ ON_MOUSE_BUTTON_UP } +function scale_ctrl_impl.on_mouse_button_up; +begin + m_move_what:=move_nothing; + + result:=false; + +end; + +{ ON_MOUSE_MOVE } +function scale_ctrl_impl.on_mouse_move; +var + xp ,yp ,dv : double; + +begin + inverse_transform_xy(@x ,@y ); + + if not button_flag then + result:=on_mouse_button_up(x ,y ) + else + begin + xp:=x + m_pdx; + yp:=y + m_pdy; + + case m_move_what of + move_value1 : + begin + if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then + m_value1:=(xp - m_xs1 ) / (m_xs2 - m_xs1 ) + else + m_value1:=(yp - m_ys1 ) / (m_ys2 - m_ys1 ); + + if m_value1 < 0.0 then + m_value1:=0.0; + + if m_value1 > m_value2 - m_min_d then + m_value1:=m_value2 - m_min_d; + + result:=true; + + end; + + move_value2 : + begin + if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then + m_value2:=(xp - m_xs1 ) / (m_xs2 - m_xs1 ) + else + m_value2:=(yp - m_ys1 ) / (m_ys2 - m_ys1 ); + + if m_value2 > 1.0 then + m_value2:=1.0; + + if m_value2 < m_value1 + m_min_d then + m_value2:=m_value1 + m_min_d; + + result:=true; + + end; + + move_slider : + begin + dv:=m_value2 - m_value1; + + if Abs(m_x2 - m_x1 ) > abs(m_y2 - m_y1 ) then + m_value1:=(xp - m_xs1 ) / (m_xs2 - m_xs1 ) + else + m_value1:=(yp - m_ys1 ) / (m_ys2 - m_ys1 ); + + m_value2:=m_value1 + dv; + + if m_value1 < 0.0 then + begin + dv:=m_value2 - m_value1; + + m_value1:=0.0; + m_value2:=m_value1 + dv; + + end; + + if m_value2 > 1.0 then + begin + dv:=m_value2 - m_value1; + + m_value2:=1.0; + m_value1:=m_value2 - dv; + + end; + + result:=true; + + end; + + else + result:=false; + + end; + + end; + +end; + +{ ON_ARROW_KEYS } +function scale_ctrl_impl.on_arrow_keys; +begin + result:=false + +end; + +{ NUM_PATHS } +function scale_ctrl_impl.num_paths; +begin + result:=5; + +end; + +{ REWIND } +procedure scale_ctrl_impl.rewind; +begin + m_idx:=path_id; + + case path_id of + 0: // Background + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1 - m_border_extra; + m_vy[0 ]:=m_y1 - m_border_extra; + m_vx[1 ]:=m_x2 + m_border_extra; + m_vy[1 ]:=m_y1 - m_border_extra; + m_vx[2 ]:=m_x2 + m_border_extra; + m_vy[2 ]:=m_y2 + m_border_extra; + m_vx[3 ]:=m_x1 - m_border_extra; + m_vy[3 ]:=m_y2 + m_border_extra; + + end; + + 1: // Border + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1; + m_vy[0 ]:=m_y1; + m_vx[1 ]:=m_x2; + m_vy[1 ]:=m_y1; + m_vx[2 ]:=m_x2; + m_vy[2 ]:=m_y2; + m_vx[3 ]:=m_x1; + m_vy[3 ]:=m_y2; + m_vx[4 ]:=m_x1 + m_border_thickness; + m_vy[4 ]:=m_y1 + m_border_thickness; + m_vx[5 ]:=m_x1 + m_border_thickness; + m_vy[5 ]:=m_y2 - m_border_thickness; + m_vx[6 ]:=m_x2 - m_border_thickness; + m_vy[6 ]:=m_y2 - m_border_thickness; + m_vx[7 ]:=m_x2 - m_border_thickness; + m_vy[7 ]:=m_y1 + m_border_thickness; + + end; + + 2: // pointer1 + begin + if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then + m_ellipse.init( + m_xs1 + (m_xs2 - m_xs1 ) * m_value1 , + (m_ys1 + m_ys2 ) / 2.0 , + m_y2 - m_y1 , + m_y2 - m_y1 ,32 ) + else + m_ellipse.init( + (m_xs1 + m_xs2 ) / 2.0, + m_ys1 + (m_ys2 - m_ys1 ) * m_value1 , + m_x2 - m_x1 , + m_x2 - m_x1 ,32 ); + + m_ellipse.rewind(0 ); + + end; + + 3: // pointer2 + begin + if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then + m_ellipse.init( + m_xs1 + (m_xs2 - m_xs1 ) * m_value2 , + (m_ys1 + m_ys2 ) / 2.0 , + m_y2 - m_y1 , + m_y2 - m_y1 ,32 ) + else + m_ellipse.init( + (m_xs1 + m_xs2 ) / 2.0 , + m_ys1 + (m_ys2 - m_ys1 ) * m_value2 , + m_x2 - m_x1 , + m_x2 - m_x1 ,32 ); + + m_ellipse.rewind(0); + + end; + + 4: // slider + begin + m_vertex:=0; + + if Abs(m_x2 - m_x1 ) > Abs(m_y2 - m_y1 ) then + begin + m_vx[0 ]:=m_xs1 + (m_xs2 - m_xs1 ) * m_value1; + m_vy[0 ]:=m_y1 - m_border_extra / 2.0; + m_vx[1 ]:=m_xs1 + (m_xs2 - m_xs1 ) * m_value2; + m_vy[1 ]:=m_vy[0 ]; + m_vx[2 ]:=m_vx[1 ]; + m_vy[2 ]:=m_y2 + m_border_extra / 2.0; + m_vx[3 ]:=m_vx[0 ]; + m_vy[3 ]:=m_vy[2 ]; + + end + else + begin + m_vx[0 ]:=m_x1 - m_border_extra / 2.0; + m_vy[0 ]:=m_ys1 + (m_ys2 - m_ys1 ) * m_value1; + m_vx[1 ]:=m_vx[0 ]; + m_vy[1 ]:=m_ys1 + (m_ys2 - m_ys1 ) * m_value2; + m_vx[2 ]:=m_x2 + m_border_extra / 2.0; + m_vy[2 ]:=m_vy[1 ]; + m_vx[3 ]:=m_vx[2 ]; + m_vy[3 ]:=m_vy[0 ]; + + end; + + end; + + end; + +end; + +{ VERTEX } +function scale_ctrl_impl.vertex; +var + cmd : unsigned; + +begin + cmd:=path_cmd_line_to; + + case m_idx of + 0 ,4 : + begin + if m_vertex = 0 then + cmd:=path_cmd_move_to; + + if m_vertex >= 4 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 1 : + begin + if (m_vertex = 0 ) or + (m_vertex = 4 ) then + cmd:=path_cmd_move_to; + + if m_vertex >= 8 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 2 ,3 : + cmd:=m_ellipse.vertex(x ,y ); + + else + cmd:=path_cmd_stop; + + end; + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ CALC_BOX } +procedure scale_ctrl_impl.calc_box; +begin + m_xs1:=m_x1 + m_border_thickness; + m_ys1:=m_y1 + m_border_thickness; + m_xs2:=m_x2 - m_border_thickness; + m_ys2:=m_y2 - m_border_thickness; + +end; + +{ CONSTRUCT } +constructor scale_ctrl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y ); + + m_background_color.ConstrDbl(1.0 ,0.9 ,0.8 ); + m_border_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_pointers_color.ConstrDbl (0.8 ,0.0 ,0.0 ,0.8 ); + m_slider_color.ConstrDbl (0.2 ,0.1 ,0.0 ,0.6 ); + + m_colors[0 ]:=@m_background_color; + m_colors[1 ]:=@m_border_color; + m_colors[2 ]:=@m_pointers_color; + m_colors[3 ]:=@m_pointers_color; + m_colors[4 ]:=@m_slider_color; + +end; + +{ BACKGROUND_COLOR_ } +procedure scale_ctrl.background_color_; +begin + m_background_color:=c^; + +end; + +{ BORDER_COLOR_ } +procedure scale_ctrl.border_color_; +begin + m_border_color:=c^; + +end; + +{ POINTERS_COLOR_ } +procedure scale_ctrl.pointers_color_; +begin + m_pointers_color:=c^; + +end; + +{ SLIDER_COLOR_ } +procedure scale_ctrl.slider_color_; +begin + m_slider_color:=c^; + +end; + +{ _COLOR } +function scale_ctrl._color; +begin + result:=m_colors[i ]; + +end; + + +END. + diff --git a/src/corelib/render/software/ctrl/agg_slider_ctrl.pas b/src/corelib/render/software/ctrl/agg_slider_ctrl.pas index 6bd35880..6c89c955 100644 --- a/src/corelib/render/software/ctrl/agg_slider_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_slider_ctrl.pas @@ -1,695 +1,695 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-//----------------------------------------------------------------------------
-//
-// classes slider_ctrl_impl, slider_ctrl
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 21.12.2005-Milano: Complete unit port
-// 18.12.2005-Milano: Unit port establishment
-//
-{ agg_slider_ctrl.pas }
-unit
- agg_slider_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- SysUtils ,
- agg_basics ,
- agg_ctrl ,
- agg_color ,
- agg_ellipse ,
- agg_path_storage ,
- agg_conv_stroke ,
- agg_gsv_text ,
- agg_math ,
- agg_math_stroke ;
-
-{ TYPES DEFINITION }
-type
- slider_ctrl_impl = object(ctrl )
- m_border_width ,
- m_border_extra ,
- m_text_thickness ,
- m_value ,
- m_preview_value ,
-
- m_min ,
- m_max : double;
-
- m_num_steps : unsigned;
- m_descending : boolean;
-
- m_label : array[0..63 ] of byte;
-
- m_xs1 ,
- m_ys1 ,
- m_xs2 ,
- m_ys2 ,
- m_pdx : double;
-
- m_mouse_move : boolean;
-
- m_vx ,
- m_vy : array[0..31 ] of double;
-
- m_ellipse : ellipse;
-
- m_idx ,
- m_vertex : unsigned;
-
- m_text : gsv_text;
- m_text_poly : conv_stroke;
- m_storage : path_storage;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false );
- destructor Destruct; virtual;
-
- procedure border_width_(t : double; extra : double = 0.0 );
-
- procedure range_ (min ,max : double );
- procedure num_steps_ (num : unsigned );
- procedure label_ (fmt : PChar );
- procedure text_thickness_(t : double );
-
- function _descending : boolean;
- procedure descending_(v : boolean );
-
- function _value : double;
- procedure value_(v : double );
-
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- // Vertex source interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- // Private
- procedure calc_box;
- function normalize_value(preview_value_flag : boolean ) : boolean;
-
- end;
-
- slider_ctrl_ptr = ^slider_ctrl;
- slider_ctrl = object(slider_ctrl_impl )
- m_background_color ,
- m_triangle_color ,
- m_text_color ,
- m_pointer_preview_color ,
- m_pointer_color : aggclr;
-
- m_colors : array[0..5 ] of aggclr_ptr;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false );
-
- procedure background_color_(c : aggclr_ptr );
- procedure pointer_color_ (c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor slider_ctrl_impl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y );
-
- m_ellipse.Construct;
- m_text.Construct;
- m_text_poly.Construct(@m_text );
- m_storage.Construct;
-
- m_border_width :=1.0;
- m_border_extra :=(y2 - y1 ) / 2;
- m_text_thickness:=1.0;
- m_pdx :=0.0;
- m_mouse_move :=false;
- m_value :=0.5;
- m_preview_value :=0.5;
- m_min :=0.0;
- m_max :=1.0;
- m_num_steps :=0;
- m_descending :=false;
-
- m_label[0 ]:=0;
-
- calc_box;
-
-end;
-
-{ DESTRUCT }
-destructor slider_ctrl_impl.Destruct;
-begin
- m_storage.Destruct;
- m_text_poly.Destruct;
- m_text.Destruct;
-
-end;
-
-{ BORDER_WIDTH_ }
-procedure slider_ctrl_impl.border_width_;
-begin
- m_border_width:=t;
- m_border_extra:=extra;
-
- calc_box;
-
-end;
-
-{ RANGE_ }
-procedure slider_ctrl_impl.range_;
-begin
- m_min:=min;
- m_max:=max;
-
-end;
-
-{ NUM_STEPS_ }
-procedure slider_ctrl_impl.num_steps_;
-begin
- m_num_steps:=num;
-
-end;
-
-{ LABEL_ }
-procedure slider_ctrl_impl.label_;
-var
- len : unsigned;
-
-begin
- m_label[0 ]:=0;
-
- if fmt <> NIL then
- begin
- len:=StrLen(fmt );
-
- if len > 63 then
- len:=63;
-
- move(fmt^ ,m_label[0 ] ,len );
-
- m_label[len ]:=0;
-
- end;
-
-end;
-
-{ TEXT_THICKNESS_ }
-procedure slider_ctrl_impl.text_thickness_;
-begin
- m_text_thickness:=t;
-
-end;
-
-{ _DESCENDING }
-function slider_ctrl_impl._descending;
-begin
- result:=m_descending;
-
-end;
-
-{ DESCENDING_ }
-procedure slider_ctrl_impl.descending_;
-begin
- m_descending:=v;
-
-end;
-
-{ _VALUE }
-function slider_ctrl_impl._value;
-begin
- result:=m_value * (m_max - m_min ) + m_min;
-
-end;
-
-{ VALUE_ }
-procedure slider_ctrl_impl.value_;
-begin
- m_preview_value:=(v - m_min ) / (m_max - m_min );
-
- if m_preview_value > 1.0 then
- m_preview_value:=1.0;
-
- if m_preview_value < 0.0 then
- m_preview_value:=0.0;
-
- normalize_value(true );
-
-end;
-
-{ IN_RECT }
-function slider_ctrl_impl.in_rect;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=
- (x >= m_x1 ) and
- (x <= m_x2 ) and
- (y >= m_y1 ) and
- (y <= m_y2 );
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function slider_ctrl_impl.on_mouse_button_down;
-var
- xp ,yp : double;
-
-begin
- inverse_transform_xy(@x ,@y );
-
- xp:=m_xs1 + (m_xs2 - m_xs1 ) * m_value;
- yp:=(m_ys1 + m_ys2 ) / 2.0;
-
- if calc_distance(x ,y ,xp ,yp ) <= m_y2 - m_y1 then
- begin
- m_pdx:=xp - x;
-
- m_mouse_move:= true;
-
- result:=true;
-
- end
- else
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function slider_ctrl_impl.on_mouse_button_up;
-begin
- m_mouse_move:=false;
-
- normalize_value(true );
-
- result:=true;
-
-end;
-
-{ ON_MOUSE_MOVE }
-function slider_ctrl_impl.on_mouse_move;
-var
- xp : double;
-
-begin
- inverse_transform_xy(@x ,@y );
-
- if not button_flag then
- begin
- on_mouse_button_up(x ,y );
-
- result:=false;
-
- exit;
-
- end;
-
- if m_mouse_move then
- begin
- xp:=x + m_pdx;
-
- m_preview_value:=(xp - m_xs1 ) / (m_xs2 - m_xs1 );
-
- if m_preview_value < 0.0 then
- m_preview_value:=0.0;
-
- if m_preview_value > 1.0 then
- m_preview_value:=1.0;
-
- result:=true;
-
- end
- else
- result:=false;
-
-end;
-
-{ ON_ARROW_KEYS }
-function slider_ctrl_impl.on_arrow_keys;
-var
- d : double;
-
-begin
- d:=0.005;
-
- if m_num_steps <> 0 then
- d:=1.0 / m_num_steps;
-
- if right or
- up then
- begin
- m_preview_value:=m_preview_value + d;
-
- if m_preview_value > 1.0 then
- m_preview_value:=1.0;
-
- normalize_value(true );
-
- result:=true;
-
- exit;
-
- end;
-
- if left or
- down then
- begin
- m_preview_value:=m_preview_value - d;
-
- if m_preview_value < 0.0 then
- m_preview_value:=0.0;
-
- normalize_value(true );
-
- result:=true;
-
- end
- else
- result:=false;
-
-end;
-
-{ NUM_PATHS }
-function slider_ctrl_impl.num_paths;
-begin
- result:=6;
-
-end;
-
-{ REWIND }
-procedure slider_ctrl_impl.rewind;
-var
- i : unsigned;
-
- d ,x : double;
-
- buf : array[0..255 ] of byte;
-
-label
- _0 ;
-
-begin
- m_idx:=path_id;
-
- case path_id of
- 0 : // Background
- begin
- _0 :
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1 - m_border_extra;
- m_vy[0 ]:=m_y1 - m_border_extra;
- m_vx[1 ]:=m_x2 + m_border_extra;
- m_vy[1 ]:=m_y1 - m_border_extra;
- m_vx[2 ]:=m_x2 + m_border_extra;
- m_vy[2 ]:=m_y2 + m_border_extra;
- m_vx[3 ]:=m_x1 - m_border_extra;
- m_vy[3 ]:=m_y2 + m_border_extra;
-
- end;
-
- 1 : // Triangle
- begin
- m_vertex:=0;
-
- if m_descending then
- begin
- m_vx[0 ]:=m_x1;
- m_vy[0 ]:=m_y1;
- m_vx[1 ]:=m_x2;
- m_vy[1 ]:=m_y1;
- m_vx[2 ]:=m_x1;
- m_vy[2 ]:=m_y2;
- m_vx[3 ]:=m_x1;
- m_vy[3 ]:=m_y1;
-
- end
- else
- begin
- m_vx[0 ]:=m_x1;
- m_vy[0 ]:=m_y1;
- m_vx[1 ]:=m_x2;
- m_vy[1 ]:=m_y1;
- m_vx[2 ]:=m_x2;
- m_vy[2 ]:=m_y2;
- m_vx[3 ]:=m_x1;
- m_vy[3 ]:=m_y1;
-
- end;
-
- end;
-
- 2 :
- begin
- m_text.text_(@m_label[0 ] );
-
- if m_label[0 ] <> 0 then
- begin
- sprintf(@buf[0 ] ,@m_label[0 ] ,_value );
-
- m_text.text_(@buf[0 ] );
-
- end;
-
- m_text.start_point_(m_x1 ,m_y1 );
- m_text.size_ ((m_y2 - m_y1 ) * 1.2 ,m_y2 - m_y1 );
-
- m_text_poly.width_ (m_text_thickness );
- m_text_poly.line_join_(round_join );
- m_text_poly.line_cap_ (round_cap );
-
- m_text_poly.rewind(0 );
-
- end;
-
- 3 : // pointer preview
- m_ellipse.init(
- m_xs1 + (m_xs2 - m_xs1 ) * m_preview_value ,
- (m_ys1 + m_ys2 ) / 2.0 ,
- m_y2 - m_y1 ,
- m_y2 - m_y1 ,
- 32 );
-
- 4 : // pointer
- begin
- normalize_value(false );
-
- m_ellipse.init(
- m_xs1 + (m_xs2 - m_xs1 ) * m_value ,
- (m_ys1 + m_ys2 ) / 2.0 ,
- m_y2 - m_y1 ,
- m_y2 - m_y1 ,
- 32 );
-
- m_ellipse.rewind(0 );
-
- end;
-
- 5 :
- begin
- m_storage.remove_all;
-
- if m_num_steps <> 0 then
- begin
- d:=(m_xs2 - m_xs1 ) / m_num_steps;
-
- if d > 0.004 then
- d:=0.004;
-
- for i:=0 to m_num_steps do
- begin
- x:=m_xs1 + (m_xs2 - m_xs1 ) * i / m_num_steps;
-
- m_storage.move_to(x ,m_y1 );
-
- m_storage.line_to(x - d * (m_x2 - m_x1 ) ,m_y1 - m_border_extra );
- m_storage.line_to(x + d * (m_x2 - m_x1 ) ,m_y1 - m_border_extra );
-
- end;
-
- end;
-
- end;
-
- else
- goto _0;
-
- end;
-
-end;
-
-{ VERTEX }
-function slider_ctrl_impl.vertex;
-var
- cmd : unsigned;
-
-begin
- cmd:=path_cmd_line_to;
-
- case m_idx of
- 0 :
- begin
- if m_vertex = 0 then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 4 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 1 :
- begin
- if m_vertex = 0 then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 4 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 2 :
- cmd:=m_text_poly.vertex(x ,y );
-
- 3 ,4 :
- cmd:=m_ellipse.vertex(x ,y );
-
- 5 :
- cmd:=m_storage.vertex(x ,y );
-
- else
- cmd:=path_cmd_stop;
-
- end;
-
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ CALC_BOX }
-procedure slider_ctrl_impl.calc_box;
-begin
- m_xs1:=m_x1 + m_border_width;
- m_ys1:=m_y1 + m_border_width;
- m_xs2:=m_x2 - m_border_width;
- m_ys2:=m_y2 - m_border_width;
-
-end;
-
-{ NORMALIZE_VALUE }
-function slider_ctrl_impl.normalize_value;
-var
- ret : boolean;
- step : int;
-
-begin
- ret:=true;
-
- if m_num_steps <> 0 then
- begin
- step:=trunc(m_preview_value * m_num_steps + 0.5 );
- ret :=m_value <> (step / m_num_steps );
-
- m_value:=step / m_num_steps;
-
- end
- else
- m_value:=m_preview_value;
-
- if preview_value_flag then
- m_preview_value:=m_value;
-
- result:=ret;
-
-end;
-
-{ CONSTRUCT }
-constructor slider_ctrl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y );
-
- m_background_color.ConstrDbl (1.0 ,0.9 ,0.8 );
- m_triangle_color.ConstrDbl (0.7 ,0.6 ,0.6 );
- m_text_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_pointer_preview_color.ConstrDbl(0.6 ,0.4 ,0.4 ,0.4 );
- m_pointer_color.ConstrDbl (0.8 ,0.0 ,0.0 ,0.6 );
-
- m_colors[0 ]:=@m_background_color;
- m_colors[1 ]:=@m_triangle_color;
- m_colors[2 ]:=@m_text_color;
- m_colors[3 ]:=@m_pointer_preview_color;
- m_colors[4 ]:=@m_pointer_color;
- m_colors[5 ]:=@m_text_color;
-
-end;
-
-{ BACKGROUND_COLOR_ }
-procedure slider_ctrl.background_color_;
-begin
- m_background_color:=c^;
-
-end;
-
-{ POINTER_COLOR_ }
-procedure slider_ctrl.pointer_color_;
-begin
- m_pointer_color:=c^;
-
-end;
-
-{ _COLOR }
-function slider_ctrl._color;
-begin
- result:=m_colors[i ];
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +//---------------------------------------------------------------------------- +// +// classes slider_ctrl_impl, slider_ctrl +// +// [Pascal Port History] ----------------------------------------------------- +// +// 21.12.2005-Milano: Complete unit port +// 18.12.2005-Milano: Unit port establishment +// +{ agg_slider_ctrl.pas } +unit + agg_slider_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + SysUtils , + agg_basics , + agg_ctrl , + agg_color , + agg_ellipse , + agg_path_storage , + agg_conv_stroke , + agg_gsv_text , + agg_math , + agg_math_stroke ; + +{ TYPES DEFINITION } +type + slider_ctrl_impl = object(ctrl ) + m_border_width , + m_border_extra , + m_text_thickness , + m_value , + m_preview_value , + + m_min , + m_max : double; + + m_num_steps : unsigned; + m_descending : boolean; + + m_label : array[0..63 ] of byte; + + m_xs1 , + m_ys1 , + m_xs2 , + m_ys2 , + m_pdx : double; + + m_mouse_move : boolean; + + m_vx , + m_vy : array[0..31 ] of double; + + m_ellipse : ellipse; + + m_idx , + m_vertex : unsigned; + + m_text : gsv_text; + m_text_poly : conv_stroke; + m_storage : path_storage; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false ); + destructor Destruct; virtual; + + procedure border_width_(t : double; extra : double = 0.0 ); + + procedure range_ (min ,max : double ); + procedure num_steps_ (num : unsigned ); + procedure label_ (fmt : PChar ); + procedure text_thickness_(t : double ); + + function _descending : boolean; + procedure descending_(v : boolean ); + + function _value : double; + procedure value_(v : double ); + + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Vertex source interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + // Private + procedure calc_box; + function normalize_value(preview_value_flag : boolean ) : boolean; + + end; + + slider_ctrl_ptr = ^slider_ctrl; + slider_ctrl = object(slider_ctrl_impl ) + m_background_color , + m_triangle_color , + m_text_color , + m_pointer_preview_color , + m_pointer_color : aggclr; + + m_colors : array[0..5 ] of aggclr_ptr; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; flip_y : boolean = false ); + + procedure background_color_(c : aggclr_ptr ); + procedure pointer_color_ (c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor slider_ctrl_impl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y ); + + m_ellipse.Construct; + m_text.Construct; + m_text_poly.Construct(@m_text ); + m_storage.Construct; + + m_border_width :=1.0; + m_border_extra :=(y2 - y1 ) / 2; + m_text_thickness:=1.0; + m_pdx :=0.0; + m_mouse_move :=false; + m_value :=0.5; + m_preview_value :=0.5; + m_min :=0.0; + m_max :=1.0; + m_num_steps :=0; + m_descending :=false; + + m_label[0 ]:=0; + + calc_box; + +end; + +{ DESTRUCT } +destructor slider_ctrl_impl.Destruct; +begin + m_storage.Destruct; + m_text_poly.Destruct; + m_text.Destruct; + +end; + +{ BORDER_WIDTH_ } +procedure slider_ctrl_impl.border_width_; +begin + m_border_width:=t; + m_border_extra:=extra; + + calc_box; + +end; + +{ RANGE_ } +procedure slider_ctrl_impl.range_; +begin + m_min:=min; + m_max:=max; + +end; + +{ NUM_STEPS_ } +procedure slider_ctrl_impl.num_steps_; +begin + m_num_steps:=num; + +end; + +{ LABEL_ } +procedure slider_ctrl_impl.label_; +var + len : unsigned; + +begin + m_label[0 ]:=0; + + if fmt <> NIL then + begin + len:=StrLen(fmt ); + + if len > 63 then + len:=63; + + move(fmt^ ,m_label[0 ] ,len ); + + m_label[len ]:=0; + + end; + +end; + +{ TEXT_THICKNESS_ } +procedure slider_ctrl_impl.text_thickness_; +begin + m_text_thickness:=t; + +end; + +{ _DESCENDING } +function slider_ctrl_impl._descending; +begin + result:=m_descending; + +end; + +{ DESCENDING_ } +procedure slider_ctrl_impl.descending_; +begin + m_descending:=v; + +end; + +{ _VALUE } +function slider_ctrl_impl._value; +begin + result:=m_value * (m_max - m_min ) + m_min; + +end; + +{ VALUE_ } +procedure slider_ctrl_impl.value_; +begin + m_preview_value:=(v - m_min ) / (m_max - m_min ); + + if m_preview_value > 1.0 then + m_preview_value:=1.0; + + if m_preview_value < 0.0 then + m_preview_value:=0.0; + + normalize_value(true ); + +end; + +{ IN_RECT } +function slider_ctrl_impl.in_rect; +begin + inverse_transform_xy(@x ,@y ); + + result:= + (x >= m_x1 ) and + (x <= m_x2 ) and + (y >= m_y1 ) and + (y <= m_y2 ); + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function slider_ctrl_impl.on_mouse_button_down; +var + xp ,yp : double; + +begin + inverse_transform_xy(@x ,@y ); + + xp:=m_xs1 + (m_xs2 - m_xs1 ) * m_value; + yp:=(m_ys1 + m_ys2 ) / 2.0; + + if calc_distance(x ,y ,xp ,yp ) <= m_y2 - m_y1 then + begin + m_pdx:=xp - x; + + m_mouse_move:= true; + + result:=true; + + end + else + result:=false; + +end; + +{ ON_MOUSE_BUTTON_UP } +function slider_ctrl_impl.on_mouse_button_up; +begin + m_mouse_move:=false; + + normalize_value(true ); + + result:=true; + +end; + +{ ON_MOUSE_MOVE } +function slider_ctrl_impl.on_mouse_move; +var + xp : double; + +begin + inverse_transform_xy(@x ,@y ); + + if not button_flag then + begin + on_mouse_button_up(x ,y ); + + result:=false; + + exit; + + end; + + if m_mouse_move then + begin + xp:=x + m_pdx; + + m_preview_value:=(xp - m_xs1 ) / (m_xs2 - m_xs1 ); + + if m_preview_value < 0.0 then + m_preview_value:=0.0; + + if m_preview_value > 1.0 then + m_preview_value:=1.0; + + result:=true; + + end + else + result:=false; + +end; + +{ ON_ARROW_KEYS } +function slider_ctrl_impl.on_arrow_keys; +var + d : double; + +begin + d:=0.005; + + if m_num_steps <> 0 then + d:=1.0 / m_num_steps; + + if right or + up then + begin + m_preview_value:=m_preview_value + d; + + if m_preview_value > 1.0 then + m_preview_value:=1.0; + + normalize_value(true ); + + result:=true; + + exit; + + end; + + if left or + down then + begin + m_preview_value:=m_preview_value - d; + + if m_preview_value < 0.0 then + m_preview_value:=0.0; + + normalize_value(true ); + + result:=true; + + end + else + result:=false; + +end; + +{ NUM_PATHS } +function slider_ctrl_impl.num_paths; +begin + result:=6; + +end; + +{ REWIND } +procedure slider_ctrl_impl.rewind; +var + i : unsigned; + + d ,x : double; + + buf : array[0..255 ] of byte; + +label + _0 ; + +begin + m_idx:=path_id; + + case path_id of + 0 : // Background + begin + _0 : + m_vertex:=0; + + m_vx[0 ]:=m_x1 - m_border_extra; + m_vy[0 ]:=m_y1 - m_border_extra; + m_vx[1 ]:=m_x2 + m_border_extra; + m_vy[1 ]:=m_y1 - m_border_extra; + m_vx[2 ]:=m_x2 + m_border_extra; + m_vy[2 ]:=m_y2 + m_border_extra; + m_vx[3 ]:=m_x1 - m_border_extra; + m_vy[3 ]:=m_y2 + m_border_extra; + + end; + + 1 : // Triangle + begin + m_vertex:=0; + + if m_descending then + begin + m_vx[0 ]:=m_x1; + m_vy[0 ]:=m_y1; + m_vx[1 ]:=m_x2; + m_vy[1 ]:=m_y1; + m_vx[2 ]:=m_x1; + m_vy[2 ]:=m_y2; + m_vx[3 ]:=m_x1; + m_vy[3 ]:=m_y1; + + end + else + begin + m_vx[0 ]:=m_x1; + m_vy[0 ]:=m_y1; + m_vx[1 ]:=m_x2; + m_vy[1 ]:=m_y1; + m_vx[2 ]:=m_x2; + m_vy[2 ]:=m_y2; + m_vx[3 ]:=m_x1; + m_vy[3 ]:=m_y1; + + end; + + end; + + 2 : + begin + m_text.text_(@m_label[0 ] ); + + if m_label[0 ] <> 0 then + begin + sprintf(@buf[0 ] ,@m_label[0 ] ,_value ); + + m_text.text_(@buf[0 ] ); + + end; + + m_text.start_point_(m_x1 ,m_y1 ); + m_text.size_ ((m_y2 - m_y1 ) * 1.2 ,m_y2 - m_y1 ); + + m_text_poly.width_ (m_text_thickness ); + m_text_poly.line_join_(round_join ); + m_text_poly.line_cap_ (round_cap ); + + m_text_poly.rewind(0 ); + + end; + + 3 : // pointer preview + m_ellipse.init( + m_xs1 + (m_xs2 - m_xs1 ) * m_preview_value , + (m_ys1 + m_ys2 ) / 2.0 , + m_y2 - m_y1 , + m_y2 - m_y1 , + 32 ); + + 4 : // pointer + begin + normalize_value(false ); + + m_ellipse.init( + m_xs1 + (m_xs2 - m_xs1 ) * m_value , + (m_ys1 + m_ys2 ) / 2.0 , + m_y2 - m_y1 , + m_y2 - m_y1 , + 32 ); + + m_ellipse.rewind(0 ); + + end; + + 5 : + begin + m_storage.remove_all; + + if m_num_steps <> 0 then + begin + d:=(m_xs2 - m_xs1 ) / m_num_steps; + + if d > 0.004 then + d:=0.004; + + for i:=0 to m_num_steps do + begin + x:=m_xs1 + (m_xs2 - m_xs1 ) * i / m_num_steps; + + m_storage.move_to(x ,m_y1 ); + + m_storage.line_to(x - d * (m_x2 - m_x1 ) ,m_y1 - m_border_extra ); + m_storage.line_to(x + d * (m_x2 - m_x1 ) ,m_y1 - m_border_extra ); + + end; + + end; + + end; + + else + goto _0; + + end; + +end; + +{ VERTEX } +function slider_ctrl_impl.vertex; +var + cmd : unsigned; + +begin + cmd:=path_cmd_line_to; + + case m_idx of + 0 : + begin + if m_vertex = 0 then + cmd:=path_cmd_move_to; + + if m_vertex >= 4 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 1 : + begin + if m_vertex = 0 then + cmd:=path_cmd_move_to; + + if m_vertex >= 4 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 2 : + cmd:=m_text_poly.vertex(x ,y ); + + 3 ,4 : + cmd:=m_ellipse.vertex(x ,y ); + + 5 : + cmd:=m_storage.vertex(x ,y ); + + else + cmd:=path_cmd_stop; + + end; + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ CALC_BOX } +procedure slider_ctrl_impl.calc_box; +begin + m_xs1:=m_x1 + m_border_width; + m_ys1:=m_y1 + m_border_width; + m_xs2:=m_x2 - m_border_width; + m_ys2:=m_y2 - m_border_width; + +end; + +{ NORMALIZE_VALUE } +function slider_ctrl_impl.normalize_value; +var + ret : boolean; + step : int; + +begin + ret:=true; + + if m_num_steps <> 0 then + begin + step:=trunc(m_preview_value * m_num_steps + 0.5 ); + ret :=m_value <> (step / m_num_steps ); + + m_value:=step / m_num_steps; + + end + else + m_value:=m_preview_value; + + if preview_value_flag then + m_preview_value:=m_value; + + result:=ret; + +end; + +{ CONSTRUCT } +constructor slider_ctrl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y ); + + m_background_color.ConstrDbl (1.0 ,0.9 ,0.8 ); + m_triangle_color.ConstrDbl (0.7 ,0.6 ,0.6 ); + m_text_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_pointer_preview_color.ConstrDbl(0.6 ,0.4 ,0.4 ,0.4 ); + m_pointer_color.ConstrDbl (0.8 ,0.0 ,0.0 ,0.6 ); + + m_colors[0 ]:=@m_background_color; + m_colors[1 ]:=@m_triangle_color; + m_colors[2 ]:=@m_text_color; + m_colors[3 ]:=@m_pointer_preview_color; + m_colors[4 ]:=@m_pointer_color; + m_colors[5 ]:=@m_text_color; + +end; + +{ BACKGROUND_COLOR_ } +procedure slider_ctrl.background_color_; +begin + m_background_color:=c^; + +end; + +{ POINTER_COLOR_ } +procedure slider_ctrl.pointer_color_; +begin + m_pointer_color:=c^; + +end; + +{ _COLOR } +function slider_ctrl._color; +begin + result:=m_colors[i ]; + +end; + +END. + diff --git a/src/corelib/render/software/ctrl/agg_spline_ctrl.pas b/src/corelib/render/software/ctrl/agg_spline_ctrl.pas index 255bdb27..71e05a1a 100644 --- a/src/corelib/render/software/ctrl/agg_spline_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_spline_ctrl.pas @@ -1,816 +1,816 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-//----------------------------------------------------------------------------
-//
-// classes spline_ctrl_impl, spline_ctrl
-//
-// Class that can be used to create an interactive control to set up
-// gamma arrays.
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 23.02.2006-Milano: Unit port establishment
-//
-{ agg_spline_ctrl.pas }
-unit
- agg_spline_ctrl ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- agg_basics ,
- agg_ellipse ,
- agg_bspline ,
- agg_conv_stroke ,
- agg_path_storage ,
- agg_trans_affine ,
- agg_color ,
- agg_ctrl ,
- agg_math ;
-
-{ TYPES DEFINITION }
-type
- spline_ctrl_impl = object(ctrl )
- m_num_pnt : unsigned;
-
- m_xp ,
- m_yp : array[0..31 ] of double;
-
- m_spline : bspline;
-
- m_spline_values : array[0..255 ] of double;
- m_spline_values8 : array[0..255 ] of int8u;
- m_border_width ,
- m_border_extra ,
- m_curve_width ,
- m_point_size ,
-
- m_xs1 ,
- m_ys1 ,
- m_xs2 ,
- m_ys2 : double;
-
- m_curve_pnt : path_storage;
- m_curve_poly : conv_stroke;
- m_ellipse : ellipse;
-
- m_idx ,
- m_vertex : unsigned;
-
- m_vx ,
- m_vy : array[0..31 ] of double;
-
- m_active_pnt ,
- m_move_pnt : int;
-
- m_pdx ,
- m_pdy : double;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; num_pnt : unsigned; flip_y : boolean = false );
- destructor Destruct; virtual;
-
- // Set other parameters
- procedure border_width_(t : double; extra : double = 0.0 );
- procedure curve_width_ (t : double );
- procedure point_size_ (s : double );
-
- // Event handlers. Just call them if the respective events
- // in your system occure. The functions return true if redrawing
- // is required.
- function in_rect(x ,y : double ) : boolean; virtual;
-
- function on_mouse_button_down(x ,y : double ) : boolean; virtual;
- function on_mouse_button_up (x ,y : double ) : boolean; virtual;
-
- function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
- function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
-
- // Spline
- procedure active_point_(i : int );
-
- function _spline : double_ptr;
- function _spline8 : int8u_ptr;
-
- function _value(x : double ) : double;
- procedure value_(idx : unsigned; y : double );
- procedure point_(idx : unsigned; x ,y : double );
-
- procedure x_(idx : unsigned; x : double );
- procedure y_(idx : unsigned; y : double );
- function _x(idx : unsigned ) : double;
- function _y(idx : unsigned ) : double;
-
- procedure update_spline;
-
- // Vertex soutce interface
- function num_paths : unsigned; virtual;
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- // Private
- procedure calc_spline_box;
- procedure calc_curve;
- function calc_xp(idx : unsigned ) : double;
- function calc_yp(idx : unsigned ) : double;
- procedure set_xp (idx : unsigned; val : double );
- procedure set_yp (idx : unsigned; val : double );
-
- end;
-
- spline_ctrl = object(spline_ctrl_impl )
- m_background_color ,
- m_border_color ,
- m_curve_color ,
- m_inactive_pnt_color ,
- m_active_pnt_color : aggclr;
-
- m_colors : array[0..4 ] of aggclr_ptr;
-
- constructor Construct(x1 ,y1 ,x2 ,y2 : double; num_pnt : unsigned; flip_y : boolean = false );
-
- procedure background_color_ (c : aggclr_ptr );
- procedure border_color_ (c : aggclr_ptr );
- procedure curve_color_ (c : aggclr_ptr );
- procedure inactive_pnt_color_(c : aggclr_ptr );
- procedure active_pnt_color_ (c : aggclr_ptr );
-
- function _color(i : unsigned ) : aggclr_ptr; virtual;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor spline_ctrl_impl.Construct;
-var
- i : unsigned;
-
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y );
-
- m_num_pnt:=num_pnt;
-
- m_border_width:=1.0;
- m_border_extra:=0.0;
- m_curve_width :=1.0;
- m_point_size :=3.0;
-
- m_spline.Construct;
- m_curve_pnt.Construct;
- m_curve_poly.Construct(@m_curve_pnt );
- m_ellipse.Construct;
-
- m_idx :=0;
- m_vertex :=0;
- m_active_pnt:=-1;
- m_move_pnt :=-1;
-
- m_pdx:=0.0;
- m_pdy:=0.0;
-
- if m_num_pnt < 4 then
- m_num_pnt:=4;
-
- if m_num_pnt > 32 then
- m_num_pnt:=32;
-
- for i:=0 to m_num_pnt - 1 do
- begin
- m_xp[i ]:=i / (m_num_pnt - 1 );
- m_yp[i ]:=0.5;
-
- end;
-
- calc_spline_box;
- update_spline;
-
-end;
-
-{ DESTRUCT }
-destructor spline_ctrl_impl.Destruct;
-begin
- m_spline.Destruct;
- m_curve_pnt.Destruct;
- m_curve_poly.Destruct;
-
-end;
-
-{ BORDER_WIDTH_ }
-procedure spline_ctrl_impl.border_width_;
-begin
- m_border_width:=t;
- m_border_extra:=extra;
-
- calc_spline_box;
-
-end;
-
-{ CURVE_WIDTH_ }
-procedure spline_ctrl_impl.curve_width_;
-begin
- m_curve_width:=t;
-
-end;
-
-{ POINT_SIZE_ }
-procedure spline_ctrl_impl.point_size_;
-begin
- m_point_size:=s;
-
-end;
-
-{ IN_RECT }
-function spline_ctrl_impl.in_rect;
-begin
- inverse_transform_xy(@x ,@y );
-
- result:=
- (x >= m_x1 ) and
- (x <= m_x2 ) and
- (y >= m_y1 ) and
- (y <= m_y2 );
-
-end;
-
-{ ON_MOUSE_BUTTON_DOWN }
-function spline_ctrl_impl.on_mouse_button_down;
-var
- i : unsigned;
-
- xp ,yp : double;
-
-begin
- inverse_transform_xy(@x ,@y );
-
- for i:=0 to m_num_pnt - 1 do
- begin
- xp:=calc_xp(i );
- yp:=calc_yp(i );
-
- if calc_distance(x ,y ,xp ,yp ) <= m_point_size + 1 then
- begin
- m_pdx:=xp - x;
- m_pdy:=yp - y;
-
- m_active_pnt:=i;
- m_move_pnt :=i;
-
- result:=true;
-
- exit;
-
- end;
-
- end;
-
- result:=false;
-
-end;
-
-{ ON_MOUSE_BUTTON_UP }
-function spline_ctrl_impl.on_mouse_button_up;
-begin
- if m_move_pnt >= 0 then
- begin
- m_move_pnt:=-1;
-
- result:=true;
-
- end
- else
- result:=false;
-
-end;
-
-{ ON_MOUSE_MOVE }
-function spline_ctrl_impl.on_mouse_move;
-var
- xp ,yp : double;
-
-begin
- inverse_transform_xy(@x ,@y );
-
- if not button_flag then
- begin
- result:=on_mouse_button_up(x ,y );
-
- exit;
-
- end;
-
- if m_move_pnt >= 0 then
- begin
- xp:=x + m_pdx;
- yp:=y + m_pdy;
-
- set_xp(m_move_pnt ,(xp - m_xs1 ) / (m_xs2 - m_xs1 ) );
- set_yp(m_move_pnt ,(yp - m_ys1 ) / (m_ys2 - m_ys1 ) );
-
- update_spline;
-
- result:=true;
-
- end
- else
- result:=false;
-
-end;
-
-{ ON_ARROW_KEYS }
-function spline_ctrl_impl.on_arrow_keys;
-var
- kx ,ky : double;
-
- ret : boolean;
-
-begin
- kx :=0.0;
- ky :=0.0;
- ret:=false;
-
- if m_active_pnt >= 0 then
- begin
- kx:=m_xp[m_active_pnt ];
- ky:=m_yp[m_active_pnt ];
-
- if left then
- begin
- kx :=kx - 0.001;
- ret:=true;
-
- end;
-
- if right then
- begin
- kx :=kx + 0.001;
- ret:=true;
-
- end;
-
- if down then
- begin
- ky :=ky - 0.001;
- ret:=true;
-
- end;
-
- if up then
- begin
- ky :=ky + 0.001;
- ret:=true;
-
- end;
-
- end;
-
- if ret then
- begin
- set_xp(m_active_pnt ,kx );
- set_yp(m_active_pnt ,ky );
-
- update_spline;
-
- end;
-
- result:=ret;
-
-end;
-
-{ ACTIVE_POINT_ }
-procedure spline_ctrl_impl.active_point_;
-begin
- m_active_pnt:=i;
-
-end;
-
-{ _SPLINE }
-function spline_ctrl_impl._spline;
-begin
- result:=@m_spline_values;
-
-end;
-
-{ _SPLINE8 }
-function spline_ctrl_impl._spline8;
-begin
- result:=@m_spline_values8;
-
-end;
-
-{ _VALUE }
-function spline_ctrl_impl._value;
-begin
- x:=m_spline.get(x );
-
- if x < 0.0 then
- x:=0.0;
-
- if x > 1.0 then
- x:=1.0;
-
- result:=x;
-
-end;
-
-{ VALUE_ }
-procedure spline_ctrl_impl.value_;
-begin
- if idx < m_num_pnt then
- set_yp(idx ,y );
-
-end;
-
-{ POINT_ }
-procedure spline_ctrl_impl.point_;
-begin
- if idx < m_num_pnt then
- begin
- set_xp(idx ,x );
- set_yp(idx ,y );
-
- end;
-
-end;
-
-{ X_ }
-procedure spline_ctrl_impl.x_;
-begin
- m_xp[idx ]:=x;
-
-end;
-
-{ Y_ }
-procedure spline_ctrl_impl.y_;
-begin
- m_yp[idx ]:=y;
-
-end;
-
-{ _X }
-function spline_ctrl_impl._x;
-begin
- result:=m_xp[idx ];
-
-end;
-
-{ _Y }
-function spline_ctrl_impl._y;
-begin
- result:=m_yp[idx ];
-
-end;
-
-{ UPDATE_SPLINE }
-procedure spline_ctrl_impl.update_spline;
-var
- i : int;
-
-begin
- m_spline.init(m_num_pnt ,@m_xp ,@m_yp );
-
- for i:=0 to 255 do
- begin
- m_spline_values[i ]:=m_spline.get(i / 255.0 );
-
- if m_spline_values[i ] < 0.0 then
- m_spline_values[i ]:=0.0;
-
- if m_spline_values[i ] > 1.0 then
- m_spline_values[i ]:=1.0;
-
- m_spline_values8[i ]:=int8u(trunc(m_spline_values[i ] * 255.0 ) );
-
- end;
-
-end;
-
-{ NUM_PATHS }
-function spline_ctrl_impl.num_paths;
-begin
- result:=5;
-
-end;
-
-{ REWIND }
-procedure spline_ctrl_impl.rewind;
-var
- i : unsigned;
-
-begin
- m_idx:=path_id;
-
- case path_id of
- 0 : // Background
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1 - m_border_extra;
- m_vy[0 ]:=m_y1 - m_border_extra;
- m_vx[1 ]:=m_x2 + m_border_extra;
- m_vy[1 ]:=m_y1 - m_border_extra;
- m_vx[2 ]:=m_x2 + m_border_extra;
- m_vy[2 ]:=m_y2 + m_border_extra;
- m_vx[3 ]:=m_x1 - m_border_extra;
- m_vy[3 ]:=m_y2 + m_border_extra;
-
- end;
-
- 1 : // Border
- begin
- m_vertex:=0;
-
- m_vx[0 ]:=m_x1;
- m_vy[0 ]:=m_y1;
- m_vx[1 ]:=m_x2;
- m_vy[1 ]:=m_y1;
- m_vx[2 ]:=m_x2;
- m_vy[2 ]:=m_y2;
- m_vx[3 ]:=m_x1;
- m_vy[3 ]:=m_y2;
- m_vx[4 ]:=m_x1 + m_border_width;
- m_vy[4 ]:=m_y1 + m_border_width;
- m_vx[5 ]:=m_x1 + m_border_width;
- m_vy[5 ]:=m_y2 - m_border_width;
- m_vx[6 ]:=m_x2 - m_border_width;
- m_vy[6 ]:=m_y2 - m_border_width;
- m_vx[7 ]:=m_x2 - m_border_width;
- m_vy[7 ]:=m_y1 + m_border_width;
-
- end;
-
- 2 : // Curve
- begin
- calc_curve;
-
- m_curve_poly.width_(m_curve_width );
- m_curve_poly.rewind(0 );
-
- end;
-
- 3 : // Inactive points
- begin
- m_curve_pnt.remove_all;
-
- for i:=0 to m_num_pnt - 1 do
- if i <> m_active_pnt then
- begin
- m_ellipse.init(
- calc_xp(i ) ,calc_yp(i ) ,
- m_point_size ,m_point_size ,32 );
-
- m_curve_pnt.add_path(@m_ellipse ,0 ,false );
-
- end;
-
- m_curve_poly.rewind(0 );
-
- end;
-
- 4 : // Active point
- begin
- m_curve_pnt.remove_all;
-
- if m_active_pnt >= 0 then
- begin
- m_ellipse.init(
- calc_xp(m_active_pnt ) ,calc_yp(m_active_pnt ) ,
- m_point_size ,m_point_size ,32 );
-
- m_curve_pnt.add_path(@m_ellipse );
-
- end;
-
- m_curve_poly.rewind(0 );
-
- end;
-
- end;
-
-end;
-
-{ VERTEX }
-function spline_ctrl_impl.vertex;
-var
- cmd : unsigned;
-
-begin
- cmd:=path_cmd_line_to;
-
- case m_idx of
- 0 :
- begin
- if m_vertex = 0 then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 4 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 1 :
- begin
- if (m_vertex = 0 ) or
- (m_vertex = 4 ) then
- cmd:=path_cmd_move_to;
-
- if m_vertex >= 8 then
- cmd:=path_cmd_stop;
-
- x^:=m_vx[m_vertex ];
- y^:=m_vy[m_vertex ];
-
- inc(m_vertex );
-
- end;
-
- 2 :
- cmd:=m_curve_poly.vertex(x ,y );
-
- 3 ,4 :
- cmd:=m_curve_pnt.vertex(x ,y );
-
- else
- cmd:=path_cmd_stop;
-
- end;
-
- if not is_stop(cmd ) then
- transform_xy(x ,y );
-
- result:=cmd;
-
-end;
-
-{ CALC_SPLINE_BOX }
-procedure spline_ctrl_impl.calc_spline_box;
-begin
- m_xs1:=m_x1 + m_border_width;
- m_ys1:=m_y1 + m_border_width;
- m_xs2:=m_x2 - m_border_width;
- m_ys2:=m_y2 - m_border_width;
-
-end;
-
-{ CALC_CURVE }
-procedure spline_ctrl_impl.calc_curve;
-var
- i : int;
-
-begin
- m_curve_pnt.remove_all;
- m_curve_pnt.move_to(m_xs1 ,m_ys1 + (m_ys2 - m_ys1 ) * m_spline_values[0 ] );
-
- for i:=1 to 255 do
- m_curve_pnt.line_to(
- m_xs1 + (m_xs2 - m_xs1 ) * i / 255.0 ,
- m_ys1 + (m_ys2 - m_ys1 ) * m_spline_values[i ] );
-
-end;
-
-{ CALC_XP }
-function spline_ctrl_impl.calc_xp;
-begin
- result:=m_xs1 + (m_xs2 - m_xs1 ) * m_xp[idx ];
-
-end;
-
-{ CALC_YP }
-function spline_ctrl_impl.calc_yp;
-begin
- result:=m_ys1 + (m_ys2 - m_ys1 ) * m_yp[idx ];
-
-end;
-
-{ SET_XP }
-procedure spline_ctrl_impl.set_xp;
-begin
- if val < 0.0 then
- val:=0.0;
-
- if val > 1.0 then
- val:=1.0;
-
- if idx = 0 then
- val:=0.0
- else
- if idx = m_num_pnt - 1 then
- val:=1.0
- else
- begin
- if val < m_xp[idx - 1 ] + 0.001 then
- val:=m_xp[idx - 1 ] + 0.001;
-
- if val > m_xp[idx + 1 ] - 0.001 then
- val:=m_xp[idx + 1 ] - 0.001;
-
- end;
-
- m_xp[idx ]:=val;
-
-end;
-
-{ SET_YP }
-procedure spline_ctrl_impl.set_yp;
-begin
- if val < 0.0 then
- val:=0.0;
-
- if val > 1.0 then
- val:=1.0;
-
- m_yp[idx ]:=val;
-
-end;
-
-{ CONSTRUCT }
-constructor spline_ctrl.Construct;
-begin
- inherited Construct(x1 ,y1 ,x2 ,y2 ,num_pnt ,flip_y );
-
- m_background_color.ConstrDbl (1.0 ,1.0 ,0.9 );
- m_border_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_curve_color.ConstrDbl (0.0 ,0.0 ,0.0 );
- m_inactive_pnt_color.ConstrDbl(0.0 ,0.0 ,0.0 );
- m_active_pnt_color.ConstrDbl (1.0 ,0.0 ,0.0 );
-
- m_colors[0 ]:=@m_background_color;
- m_colors[1 ]:=@m_border_color;
- m_colors[2 ]:=@m_curve_color;
- m_colors[3 ]:=@m_inactive_pnt_color;
- m_colors[4 ]:=@m_active_pnt_color;
-
-end;
-
-{ BACKGROUND_COLOR_ }
-procedure spline_ctrl.background_color_;
-begin
- m_background_color:=c^;
-
-end;
-
-{ BORDER_COLOR_ }
-procedure spline_ctrl.border_color_;
-begin
- m_border_color:=c^;
-
-end;
-
-{ CURVE_COLOR_ }
-procedure spline_ctrl.curve_color_;
-begin
- m_curve_color:=c^;
-
-end;
-
-{ INACTIVE_PNT_COLOR_ }
-procedure spline_ctrl.inactive_pnt_color_;
-begin
- m_inactive_pnt_color:=c^;
-
-end;
-
-{ ACTIVE_PNT_COLOR_ }
-procedure spline_ctrl.active_pnt_color_;
-begin
- m_active_pnt_color:=c^;
-
-end;
-
-{ _COLOR }
-function spline_ctrl._color;
-begin
- result:=m_colors[i ];
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +//---------------------------------------------------------------------------- +// +// classes spline_ctrl_impl, spline_ctrl +// +// Class that can be used to create an interactive control to set up +// gamma arrays. +// +// [Pascal Port History] ----------------------------------------------------- +// +// 23.02.2006-Milano: Unit port establishment +// +{ agg_spline_ctrl.pas } +unit + agg_spline_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + agg_basics , + agg_ellipse , + agg_bspline , + agg_conv_stroke , + agg_path_storage , + agg_trans_affine , + agg_color , + agg_ctrl , + agg_math ; + +{ TYPES DEFINITION } +type + spline_ctrl_impl = object(ctrl ) + m_num_pnt : unsigned; + + m_xp , + m_yp : array[0..31 ] of double; + + m_spline : bspline; + + m_spline_values : array[0..255 ] of double; + m_spline_values8 : array[0..255 ] of int8u; + m_border_width , + m_border_extra , + m_curve_width , + m_point_size , + + m_xs1 , + m_ys1 , + m_xs2 , + m_ys2 : double; + + m_curve_pnt : path_storage; + m_curve_poly : conv_stroke; + m_ellipse : ellipse; + + m_idx , + m_vertex : unsigned; + + m_vx , + m_vy : array[0..31 ] of double; + + m_active_pnt , + m_move_pnt : int; + + m_pdx , + m_pdy : double; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; num_pnt : unsigned; flip_y : boolean = false ); + destructor Destruct; virtual; + + // Set other parameters + procedure border_width_(t : double; extra : double = 0.0 ); + procedure curve_width_ (t : double ); + procedure point_size_ (s : double ); + + // Event handlers. Just call them if the respective events + // in your system occure. The functions return true if redrawing + // is required. + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Spline + procedure active_point_(i : int ); + + function _spline : double_ptr; + function _spline8 : int8u_ptr; + + function _value(x : double ) : double; + procedure value_(idx : unsigned; y : double ); + procedure point_(idx : unsigned; x ,y : double ); + + procedure x_(idx : unsigned; x : double ); + procedure y_(idx : unsigned; y : double ); + function _x(idx : unsigned ) : double; + function _y(idx : unsigned ) : double; + + procedure update_spline; + + // Vertex soutce interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + // Private + procedure calc_spline_box; + procedure calc_curve; + function calc_xp(idx : unsigned ) : double; + function calc_yp(idx : unsigned ) : double; + procedure set_xp (idx : unsigned; val : double ); + procedure set_yp (idx : unsigned; val : double ); + + end; + + spline_ctrl = object(spline_ctrl_impl ) + m_background_color , + m_border_color , + m_curve_color , + m_inactive_pnt_color , + m_active_pnt_color : aggclr; + + m_colors : array[0..4 ] of aggclr_ptr; + + constructor Construct(x1 ,y1 ,x2 ,y2 : double; num_pnt : unsigned; flip_y : boolean = false ); + + procedure background_color_ (c : aggclr_ptr ); + procedure border_color_ (c : aggclr_ptr ); + procedure curve_color_ (c : aggclr_ptr ); + procedure inactive_pnt_color_(c : aggclr_ptr ); + procedure active_pnt_color_ (c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor spline_ctrl_impl.Construct; +var + i : unsigned; + +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,flip_y ); + + m_num_pnt:=num_pnt; + + m_border_width:=1.0; + m_border_extra:=0.0; + m_curve_width :=1.0; + m_point_size :=3.0; + + m_spline.Construct; + m_curve_pnt.Construct; + m_curve_poly.Construct(@m_curve_pnt ); + m_ellipse.Construct; + + m_idx :=0; + m_vertex :=0; + m_active_pnt:=-1; + m_move_pnt :=-1; + + m_pdx:=0.0; + m_pdy:=0.0; + + if m_num_pnt < 4 then + m_num_pnt:=4; + + if m_num_pnt > 32 then + m_num_pnt:=32; + + for i:=0 to m_num_pnt - 1 do + begin + m_xp[i ]:=i / (m_num_pnt - 1 ); + m_yp[i ]:=0.5; + + end; + + calc_spline_box; + update_spline; + +end; + +{ DESTRUCT } +destructor spline_ctrl_impl.Destruct; +begin + m_spline.Destruct; + m_curve_pnt.Destruct; + m_curve_poly.Destruct; + +end; + +{ BORDER_WIDTH_ } +procedure spline_ctrl_impl.border_width_; +begin + m_border_width:=t; + m_border_extra:=extra; + + calc_spline_box; + +end; + +{ CURVE_WIDTH_ } +procedure spline_ctrl_impl.curve_width_; +begin + m_curve_width:=t; + +end; + +{ POINT_SIZE_ } +procedure spline_ctrl_impl.point_size_; +begin + m_point_size:=s; + +end; + +{ IN_RECT } +function spline_ctrl_impl.in_rect; +begin + inverse_transform_xy(@x ,@y ); + + result:= + (x >= m_x1 ) and + (x <= m_x2 ) and + (y >= m_y1 ) and + (y <= m_y2 ); + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function spline_ctrl_impl.on_mouse_button_down; +var + i : unsigned; + + xp ,yp : double; + +begin + inverse_transform_xy(@x ,@y ); + + for i:=0 to m_num_pnt - 1 do + begin + xp:=calc_xp(i ); + yp:=calc_yp(i ); + + if calc_distance(x ,y ,xp ,yp ) <= m_point_size + 1 then + begin + m_pdx:=xp - x; + m_pdy:=yp - y; + + m_active_pnt:=i; + m_move_pnt :=i; + + result:=true; + + exit; + + end; + + end; + + result:=false; + +end; + +{ ON_MOUSE_BUTTON_UP } +function spline_ctrl_impl.on_mouse_button_up; +begin + if m_move_pnt >= 0 then + begin + m_move_pnt:=-1; + + result:=true; + + end + else + result:=false; + +end; + +{ ON_MOUSE_MOVE } +function spline_ctrl_impl.on_mouse_move; +var + xp ,yp : double; + +begin + inverse_transform_xy(@x ,@y ); + + if not button_flag then + begin + result:=on_mouse_button_up(x ,y ); + + exit; + + end; + + if m_move_pnt >= 0 then + begin + xp:=x + m_pdx; + yp:=y + m_pdy; + + set_xp(m_move_pnt ,(xp - m_xs1 ) / (m_xs2 - m_xs1 ) ); + set_yp(m_move_pnt ,(yp - m_ys1 ) / (m_ys2 - m_ys1 ) ); + + update_spline; + + result:=true; + + end + else + result:=false; + +end; + +{ ON_ARROW_KEYS } +function spline_ctrl_impl.on_arrow_keys; +var + kx ,ky : double; + + ret : boolean; + +begin + kx :=0.0; + ky :=0.0; + ret:=false; + + if m_active_pnt >= 0 then + begin + kx:=m_xp[m_active_pnt ]; + ky:=m_yp[m_active_pnt ]; + + if left then + begin + kx :=kx - 0.001; + ret:=true; + + end; + + if right then + begin + kx :=kx + 0.001; + ret:=true; + + end; + + if down then + begin + ky :=ky - 0.001; + ret:=true; + + end; + + if up then + begin + ky :=ky + 0.001; + ret:=true; + + end; + + end; + + if ret then + begin + set_xp(m_active_pnt ,kx ); + set_yp(m_active_pnt ,ky ); + + update_spline; + + end; + + result:=ret; + +end; + +{ ACTIVE_POINT_ } +procedure spline_ctrl_impl.active_point_; +begin + m_active_pnt:=i; + +end; + +{ _SPLINE } +function spline_ctrl_impl._spline; +begin + result:=@m_spline_values; + +end; + +{ _SPLINE8 } +function spline_ctrl_impl._spline8; +begin + result:=@m_spline_values8; + +end; + +{ _VALUE } +function spline_ctrl_impl._value; +begin + x:=m_spline.get(x ); + + if x < 0.0 then + x:=0.0; + + if x > 1.0 then + x:=1.0; + + result:=x; + +end; + +{ VALUE_ } +procedure spline_ctrl_impl.value_; +begin + if idx < m_num_pnt then + set_yp(idx ,y ); + +end; + +{ POINT_ } +procedure spline_ctrl_impl.point_; +begin + if idx < m_num_pnt then + begin + set_xp(idx ,x ); + set_yp(idx ,y ); + + end; + +end; + +{ X_ } +procedure spline_ctrl_impl.x_; +begin + m_xp[idx ]:=x; + +end; + +{ Y_ } +procedure spline_ctrl_impl.y_; +begin + m_yp[idx ]:=y; + +end; + +{ _X } +function spline_ctrl_impl._x; +begin + result:=m_xp[idx ]; + +end; + +{ _Y } +function spline_ctrl_impl._y; +begin + result:=m_yp[idx ]; + +end; + +{ UPDATE_SPLINE } +procedure spline_ctrl_impl.update_spline; +var + i : int; + +begin + m_spline.init(m_num_pnt ,@m_xp ,@m_yp ); + + for i:=0 to 255 do + begin + m_spline_values[i ]:=m_spline.get(i / 255.0 ); + + if m_spline_values[i ] < 0.0 then + m_spline_values[i ]:=0.0; + + if m_spline_values[i ] > 1.0 then + m_spline_values[i ]:=1.0; + + m_spline_values8[i ]:=int8u(trunc(m_spline_values[i ] * 255.0 ) ); + + end; + +end; + +{ NUM_PATHS } +function spline_ctrl_impl.num_paths; +begin + result:=5; + +end; + +{ REWIND } +procedure spline_ctrl_impl.rewind; +var + i : unsigned; + +begin + m_idx:=path_id; + + case path_id of + 0 : // Background + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1 - m_border_extra; + m_vy[0 ]:=m_y1 - m_border_extra; + m_vx[1 ]:=m_x2 + m_border_extra; + m_vy[1 ]:=m_y1 - m_border_extra; + m_vx[2 ]:=m_x2 + m_border_extra; + m_vy[2 ]:=m_y2 + m_border_extra; + m_vx[3 ]:=m_x1 - m_border_extra; + m_vy[3 ]:=m_y2 + m_border_extra; + + end; + + 1 : // Border + begin + m_vertex:=0; + + m_vx[0 ]:=m_x1; + m_vy[0 ]:=m_y1; + m_vx[1 ]:=m_x2; + m_vy[1 ]:=m_y1; + m_vx[2 ]:=m_x2; + m_vy[2 ]:=m_y2; + m_vx[3 ]:=m_x1; + m_vy[3 ]:=m_y2; + m_vx[4 ]:=m_x1 + m_border_width; + m_vy[4 ]:=m_y1 + m_border_width; + m_vx[5 ]:=m_x1 + m_border_width; + m_vy[5 ]:=m_y2 - m_border_width; + m_vx[6 ]:=m_x2 - m_border_width; + m_vy[6 ]:=m_y2 - m_border_width; + m_vx[7 ]:=m_x2 - m_border_width; + m_vy[7 ]:=m_y1 + m_border_width; + + end; + + 2 : // Curve + begin + calc_curve; + + m_curve_poly.width_(m_curve_width ); + m_curve_poly.rewind(0 ); + + end; + + 3 : // Inactive points + begin + m_curve_pnt.remove_all; + + for i:=0 to m_num_pnt - 1 do + if i <> m_active_pnt then + begin + m_ellipse.init( + calc_xp(i ) ,calc_yp(i ) , + m_point_size ,m_point_size ,32 ); + + m_curve_pnt.add_path(@m_ellipse ,0 ,false ); + + end; + + m_curve_poly.rewind(0 ); + + end; + + 4 : // Active point + begin + m_curve_pnt.remove_all; + + if m_active_pnt >= 0 then + begin + m_ellipse.init( + calc_xp(m_active_pnt ) ,calc_yp(m_active_pnt ) , + m_point_size ,m_point_size ,32 ); + + m_curve_pnt.add_path(@m_ellipse ); + + end; + + m_curve_poly.rewind(0 ); + + end; + + end; + +end; + +{ VERTEX } +function spline_ctrl_impl.vertex; +var + cmd : unsigned; + +begin + cmd:=path_cmd_line_to; + + case m_idx of + 0 : + begin + if m_vertex = 0 then + cmd:=path_cmd_move_to; + + if m_vertex >= 4 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 1 : + begin + if (m_vertex = 0 ) or + (m_vertex = 4 ) then + cmd:=path_cmd_move_to; + + if m_vertex >= 8 then + cmd:=path_cmd_stop; + + x^:=m_vx[m_vertex ]; + y^:=m_vy[m_vertex ]; + + inc(m_vertex ); + + end; + + 2 : + cmd:=m_curve_poly.vertex(x ,y ); + + 3 ,4 : + cmd:=m_curve_pnt.vertex(x ,y ); + + else + cmd:=path_cmd_stop; + + end; + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ CALC_SPLINE_BOX } +procedure spline_ctrl_impl.calc_spline_box; +begin + m_xs1:=m_x1 + m_border_width; + m_ys1:=m_y1 + m_border_width; + m_xs2:=m_x2 - m_border_width; + m_ys2:=m_y2 - m_border_width; + +end; + +{ CALC_CURVE } +procedure spline_ctrl_impl.calc_curve; +var + i : int; + +begin + m_curve_pnt.remove_all; + m_curve_pnt.move_to(m_xs1 ,m_ys1 + (m_ys2 - m_ys1 ) * m_spline_values[0 ] ); + + for i:=1 to 255 do + m_curve_pnt.line_to( + m_xs1 + (m_xs2 - m_xs1 ) * i / 255.0 , + m_ys1 + (m_ys2 - m_ys1 ) * m_spline_values[i ] ); + +end; + +{ CALC_XP } +function spline_ctrl_impl.calc_xp; +begin + result:=m_xs1 + (m_xs2 - m_xs1 ) * m_xp[idx ]; + +end; + +{ CALC_YP } +function spline_ctrl_impl.calc_yp; +begin + result:=m_ys1 + (m_ys2 - m_ys1 ) * m_yp[idx ]; + +end; + +{ SET_XP } +procedure spline_ctrl_impl.set_xp; +begin + if val < 0.0 then + val:=0.0; + + if val > 1.0 then + val:=1.0; + + if idx = 0 then + val:=0.0 + else + if idx = m_num_pnt - 1 then + val:=1.0 + else + begin + if val < m_xp[idx - 1 ] + 0.001 then + val:=m_xp[idx - 1 ] + 0.001; + + if val > m_xp[idx + 1 ] - 0.001 then + val:=m_xp[idx + 1 ] - 0.001; + + end; + + m_xp[idx ]:=val; + +end; + +{ SET_YP } +procedure spline_ctrl_impl.set_yp; +begin + if val < 0.0 then + val:=0.0; + + if val > 1.0 then + val:=1.0; + + m_yp[idx ]:=val; + +end; + +{ CONSTRUCT } +constructor spline_ctrl.Construct; +begin + inherited Construct(x1 ,y1 ,x2 ,y2 ,num_pnt ,flip_y ); + + m_background_color.ConstrDbl (1.0 ,1.0 ,0.9 ); + m_border_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_curve_color.ConstrDbl (0.0 ,0.0 ,0.0 ); + m_inactive_pnt_color.ConstrDbl(0.0 ,0.0 ,0.0 ); + m_active_pnt_color.ConstrDbl (1.0 ,0.0 ,0.0 ); + + m_colors[0 ]:=@m_background_color; + m_colors[1 ]:=@m_border_color; + m_colors[2 ]:=@m_curve_color; + m_colors[3 ]:=@m_inactive_pnt_color; + m_colors[4 ]:=@m_active_pnt_color; + +end; + +{ BACKGROUND_COLOR_ } +procedure spline_ctrl.background_color_; +begin + m_background_color:=c^; + +end; + +{ BORDER_COLOR_ } +procedure spline_ctrl.border_color_; +begin + m_border_color:=c^; + +end; + +{ CURVE_COLOR_ } +procedure spline_ctrl.curve_color_; +begin + m_curve_color:=c^; + +end; + +{ INACTIVE_PNT_COLOR_ } +procedure spline_ctrl.inactive_pnt_color_; +begin + m_inactive_pnt_color:=c^; + +end; + +{ ACTIVE_PNT_COLOR_ } +procedure spline_ctrl.active_pnt_color_; +begin + m_active_pnt_color:=c^; + +end; + +{ _COLOR } +function spline_ctrl._color; +begin + result:=m_colors[i ]; + +end; + +END. + diff --git a/src/corelib/render/software/svg/agg_svg_exception.pas b/src/corelib/render/software/svg/agg_svg_exception.pas index 0a52836e..97ebe3e5 100644 --- a/src/corelib/render/software/svg/agg_svg_exception.pas +++ b/src/corelib/render/software/svg/agg_svg_exception.pas @@ -1,172 +1,172 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 23.06.2006-Milano: ptrcomp adjustments
-// 24.04.2006-Milano: Unit port establishment
-//
-{ agg_svg_exception.pas }
-unit
- agg_svg_exception ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- SysUtils ,
- agg_basics ;
-
-{ TYPES DEFINITION }
-type
- svg_exception_ptr = ^svg_exception;
- svg_exception = class(Exception )
- m_msg : pointer;
-
- constructor Construct; overload;
- constructor Construct(fmt : PChar ); overload;
- constructor Construct(exc : svg_exception_ptr ); overload;
-
- procedure Free;
- function _msg : char_ptr;
-
- end;
-
-{ GLOBAL PROCEDURES }
- function get_double(ptr : agg_basics.char_ptr ) : double;
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor svg_exception.Construct;
-begin
- m_msg:=NIL;
-
-end;
-
-{ CONSTRUCT }
-constructor svg_exception.Construct(fmt : PChar );
-var
- max : int;
-
-begin
- m_msg:=NIL;
-
- if agg_getmem(m_msg ,4096 ) then
- begin
- max:=StrLen(fmt );
-
- if max > 4095 then
- max:=4095;
-
- move(fmt[0 ] ,m_msg^ ,max );
-
- int8_ptr(ptrcomp(m_msg ) + max )^:=0;
-
- end;
-
-end;
-
-{ CONSTRUCT }
-constructor svg_exception.Construct(exc : svg_exception_ptr );
-var
- max : int;
-
-begin
- m_msg:=NIL;
-
- if (exc <> NIL ) and
- (exc.m_msg <> NIL ) then
- if agg_getmem(m_msg ,4096 ) then
- begin
- max:=StrLen(exc.m_msg );
-
- if max > 4095 then
- max:=4095;
-
- move(exc.m_msg^ ,m_msg^ ,max );
-
- int8_ptr(ptrcomp(m_msg ) + max )^:=0;
-
- end;
-
-end;
-
-{ FREE }
-procedure svg_exception.Free;
-begin
- if m_msg <> NIL then
- agg_freemem(m_msg ,4096 );
-
-end;
-
-{ _MSG }
-function svg_exception._msg;
-begin
- result:=char_ptr(m_msg );
-
-end;
-
-{ GET_DOUBLE }
-function get_double;
-var
- buf : array[0..49 ] of char;
- dst ,
- max : char_ptr;
- err : integer;
-
-begin
- dst:=@buf[0 ];
- max:=@buf[48 ];
-
- while ptr^ <> #0 do
- begin
- case ptr^ of
- '-' ,'.' ,'0'..'9' :
- if dst <> max then
- begin
- dst^:=ptr^;
-
- inc(ptrcomp(dst ) );
-
- end
- else
- break;
-
- else
- break;
-
- end;
-
- inc(ptrcomp(ptr ) );
-
- end;
-
- dst^:=#0;
-
- val(PChar(@buf[0 ] ) ,result ,err );
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 23.06.2006-Milano: ptrcomp adjustments +// 24.04.2006-Milano: Unit port establishment +// +{ agg_svg_exception.pas } +unit + agg_svg_exception ; + +INTERFACE + +{$I agg_mode.inc } + +uses + SysUtils , + agg_basics ; + +{ TYPES DEFINITION } +type + svg_exception_ptr = ^svg_exception; + svg_exception = class(Exception ) + m_msg : pointer; + + constructor Construct; overload; + constructor Construct(fmt : PChar ); overload; + constructor Construct(exc : svg_exception_ptr ); overload; + + procedure Free; + function _msg : char_ptr; + + end; + +{ GLOBAL PROCEDURES } + function get_double(ptr : agg_basics.char_ptr ) : double; + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor svg_exception.Construct; +begin + m_msg:=NIL; + +end; + +{ CONSTRUCT } +constructor svg_exception.Construct(fmt : PChar ); +var + max : int; + +begin + m_msg:=NIL; + + if agg_getmem(m_msg ,4096 ) then + begin + max:=StrLen(fmt ); + + if max > 4095 then + max:=4095; + + move(fmt[0 ] ,m_msg^ ,max ); + + int8_ptr(ptrcomp(m_msg ) + max )^:=0; + + end; + +end; + +{ CONSTRUCT } +constructor svg_exception.Construct(exc : svg_exception_ptr ); +var + max : int; + +begin + m_msg:=NIL; + + if (exc <> NIL ) and + (exc.m_msg <> NIL ) then + if agg_getmem(m_msg ,4096 ) then + begin + max:=StrLen(exc.m_msg ); + + if max > 4095 then + max:=4095; + + move(exc.m_msg^ ,m_msg^ ,max ); + + int8_ptr(ptrcomp(m_msg ) + max )^:=0; + + end; + +end; + +{ FREE } +procedure svg_exception.Free; +begin + if m_msg <> NIL then + agg_freemem(m_msg ,4096 ); + +end; + +{ _MSG } +function svg_exception._msg; +begin + result:=char_ptr(m_msg ); + +end; + +{ GET_DOUBLE } +function get_double; +var + buf : array[0..49 ] of char; + dst , + max : char_ptr; + err : integer; + +begin + dst:=@buf[0 ]; + max:=@buf[48 ]; + + while ptr^ <> #0 do + begin + case ptr^ of + '-' ,'.' ,'0'..'9' : + if dst <> max then + begin + dst^:=ptr^; + + inc(ptrcomp(dst ) ); + + end + else + break; + + else + break; + + end; + + inc(ptrcomp(ptr ) ); + + end; + + dst^:=#0; + + val(PChar(@buf[0 ] ) ,result ,err ); + +end; + +END. + diff --git a/src/corelib/render/software/svg/agg_svg_parser.pas b/src/corelib/render/software/svg/agg_svg_parser.pas index a2ec372a..0dce2706 100644 --- a/src/corelib/render/software/svg/agg_svg_parser.pas +++ b/src/corelib/render/software/svg/agg_svg_parser.pas @@ -1,1386 +1,1386 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 03.01.2007-Milano: Adjustments for ExpatWrap (Win,Linux & Mac)
-// 23.06.2006-Milano: ptrcomp adjustments
-// 24.04.2006-Milano: Unit port establishment
-//
-{ agg_svg_parser.pas }
-unit
- agg_svg_parser ;
-
-INTERFACE
-
-{$DEFINE EXPAT_WRAPPER }
-{$I agg_mode.inc }
-
-uses
- SysUtils ,
- agg_basics ,
- agg_color ,
- agg_svg_path_tokenizer ,
- agg_svg_path_renderer ,
- agg_svg_exception ,
- agg_trans_affine ,
- agg_math_stroke ,
- expat ,
- file_utils_ ;
-
-{ TYPES DEFINITION }
-const
- buf_size = 512;
-
-type
- parser_ptr = ^parser;
- parser = object
- m_path : path_renderer_ptr;
- m_tokenizer : path_tokenizer;
-
- m_buf ,
- m_title : char_ptr;
-
- m_title_len : unsigned;
- m_title_flag ,
- m_path_flag : boolean;
- m_attr_name ,
- m_attr_value : char_ptr;
-
- m_attr_name_len ,
- m_attr_name_aloc ,
- m_attr_value_len ,
- m_attr_value_aloc : unsigned;
-
- constructor Construct(path : path_renderer_ptr );
- destructor Destruct;
-
- procedure parse(fname : shortstring );
- function title : char_ptr;
-
- // XML event handlers
- procedure parse_attr (attr : char_ptr_ptr ); overload;
- procedure parse_path (attr : char_ptr_ptr );
- procedure parse_poly (attr : char_ptr_ptr; close_flag : boolean );
- procedure parse_rect (attr : char_ptr_ptr );
- procedure parse_line (attr : char_ptr_ptr );
- procedure parse_style (str : agg_basics.char_ptr );
- procedure parse_transform(str : agg_basics.char_ptr );
-
- function parse_matrix (str : agg_basics.char_ptr ) : unsigned;
- function parse_translate(str : agg_basics.char_ptr ) : unsigned;
- function parse_rotate (str : agg_basics.char_ptr ) : unsigned;
- function parse_scale (str : agg_basics.char_ptr ) : unsigned;
- function parse_skew_x (str : agg_basics.char_ptr ) : unsigned;
- function parse_skew_y (str : agg_basics.char_ptr ) : unsigned;
-
- function parse_attr (name ,value : agg_basics.char_ptr ) : boolean; overload;
- function parse_name_value(nv_start ,nv_end : agg_basics.char_ptr ) : boolean;
-
- procedure copy_name (start ,end_ : agg_basics.char_ptr );
- procedure copy_value(start ,end_ : agg_basics.char_ptr );
-
- end;
-
-{ GLOBAL PROCEDURES }
- procedure start_element(data : pointer; el : char_ptr; attr : char_ptr_ptr ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF }
- procedure end_element (data : pointer; el : char_ptr ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF }
- procedure content (data : pointer; s : char_ptr; len : int ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-type
- named_color_ptr = ^named_color;
- named_color = record
- name : array[0..21 ] of char;
-
- r ,g ,b ,a : int8u;
-
- end;
-
-const
- colors_num = 148;
-
- colors : array[0..colors_num - 1 ] of named_color =
- ((name:'aliceblue'; r:240; g:248; b:255; a:255 ) ,
- (name:'antiquewhite'; r:250; g:235; b:215; a:255 ) ,
- (name:'aqua'; r:0; g:255; b:255; a:255 ) ,
- (name:'aquamarine'; r:127; g:255; b:212; a:255 ) ,
- (name:'azure'; r:240; g:255; b:255; a:255 ) ,
- (name:'beige'; r:245; g:245; b:220; a:255 ) ,
- (name:'bisque'; r:255; g:228; b:196; a:255 ) ,
- (name:'black'; r:0; g:0; b:0; a:255 ) ,
- (name:'blanchedalmond'; r:255; g:235; b:205; a:255 ) ,
- (name:'blue'; r:0; g:0; b:255; a:255 ) ,
- (name:'blueviolet'; r:138; g:43; b:226; a:255 ) ,
- (name:'brown'; r:165; g:42; b:42; a:255 ) ,
- (name:'burlywood'; r:222; g:184; b:135; a:255 ) ,
- (name:'cadetblue'; r:95; g:158; b:160; a:255 ) ,
- (name:'chartreuse'; r:127; g:255; b:0; a:255 ) ,
- (name:'chocolate'; r:210; g:105; b:30; a:255 ) ,
- (name:'coral'; r:255; g:127; b:80; a:255 ) ,
- (name:'cornflowerblue'; r:100; g:149; b:237; a:255 ) ,
- (name:'cornsilk'; r:255; g:248; b:220; a:255 ) ,
- (name:'crimson'; r:220; g:20; b:60; a:255 ) ,
- (name:'cyan'; r:0; g:255; b:255; a:255 ) ,
- (name:'darkblue'; r:0; g:0; b:139; a:255 ) ,
- (name:'darkcyan'; r:0; g:139; b:139; a:255 ) ,
- (name:'darkgoldenrod'; r:184; g:134; b:11; a:255 ) ,
- (name:'darkgray'; r:169; g:169; b:169; a:255 ) ,
- (name:'darkgreen'; r:0; g:100; b:0; a:255 ) ,
- (name:'darkgrey'; r:169; g:169; b:169; a:255 ) ,
- (name:'darkkhaki'; r:189; g:183; b:107; a:255 ) ,
- (name:'darkmagenta'; r:139; g:0; b:139; a:255 ) ,
- (name:'darkolivegreen'; r:85; g:107; b:47; a:255 ) ,
- (name:'darkorange'; r:255; g:140; b:0; a:255 ) ,
- (name:'darkorchid'; r:153; g:50; b:204; a:255 ) ,
- (name:'darkred'; r:139; g:0; b:0; a:255 ) ,
- (name:'darksalmon'; r:233; g:150; b:122; a:255 ) ,
- (name:'darkseagreen'; r:143; g:188; b:143; a:255 ) ,
- (name:'darkslateblue'; r:72; g:61; b:139; a:255 ) ,
- (name:'darkslategray'; r:47; g:79; b:79; a:255 ) ,
- (name:'darkslategrey'; r:47; g:79; b:79; a:255 ) ,
- (name:'darkturquoise'; r:0; g:206; b:209; a:255 ) ,
- (name:'darkviolet'; r:148; g:0; b:211; a:255 ) ,
- (name:'deeppink'; r:255; g:20; b:147; a:255 ) ,
- (name:'deepskyblue'; r:0; g:191; b:255; a:255 ) ,
- (name:'dimgray'; r:105; g:105; b:105; a:255 ) ,
- (name:'dimgrey'; r:105; g:105; b:105; a:255 ) ,
- (name:'dodgerblue'; r:30; g:144; b:255; a:255 ) ,
- (name:'firebrick'; r:178; g:34; b:34; a:255 ) ,
- (name:'floralwhite'; r:255; g:250; b:240; a:255 ) ,
- (name:'forestgreen'; r:34; g:139; b:34; a:255 ) ,
- (name:'fuchsia'; r:255; g:0; b:255; a:255 ) ,
- (name:'gainsboro'; r:220; g:220; b:220; a:255 ) ,
- (name:'ghostwhite'; r:248; g:248; b:255; a:255 ) ,
- (name:'gold'; r:255; g:215; b:0; a:255 ) ,
- (name:'goldenrod'; r:218; g:165; b:32; a:255 ) ,
- (name:'gray'; r:128; g:128; b:128; a:255 ) ,
- (name:'green'; r:0; g:128; b:0; a:255 ) ,
- (name:'greenyellow'; r:173; g:255; b:47; a:255 ) ,
- (name:'grey'; r:128; g:128; b:128; a:255 ) ,
- (name:'honeydew'; r:240; g:255; b:240; a:255 ) ,
- (name:'hotpink'; r:255; g:105; b:180; a:255 ) ,
- (name:'indianred'; r:205; g:92; b:92; a:255 ) ,
- (name:'indigo'; r:75; g:0; b:130; a:255 ) ,
- (name:'ivory'; r:255; g:255; b:240; a:255 ) ,
- (name:'khaki'; r:240; g:230; b:140; a:255 ) ,
- (name:'lavender'; r:230; g:230; b:250; a:255 ) ,
- (name:'lavenderblush'; r:255; g:240; b:245; a:255 ) ,
- (name:'lawngreen'; r:124; g:252; b:0; a:255 ) ,
- (name:'lemonchiffon'; r:255; g:250; b:205; a:255 ) ,
- (name:'lightblue'; r:173; g:216; b:230; a:255 ) ,
- (name:'lightcoral'; r:240; g:128; b:128; a:255 ) ,
- (name:'lightcyan'; r:224; g:255; b:255; a:255 ) ,
- (name:'lightgoldenrodyellow'; r:250; g:250; b:210; a:255 ) ,
- (name:'lightgray'; r:211; g:211; b:211; a:255 ) ,
- (name:'lightgreen'; r:144; g:238; b:144; a:255 ) ,
- (name:'lightgrey'; r:211; g:211; b:211; a:255 ) ,
- (name:'lightpink'; r:255; g:182; b:193; a:255 ) ,
- (name:'lightsalmon'; r:255; g:160; b:122; a:255 ) ,
- (name:'lightseagreen'; r:32; g:178; b:170; a:255 ) ,
- (name:'lightskyblue'; r:135; g:206; b:250; a:255 ) ,
- (name:'lightslategray'; r:119; g:136; b:153; a:255 ) ,
- (name:'lightslategrey'; r:119; g:136; b:153; a:255 ) ,
- (name:'lightsteelblue'; r:176; g:196; b:222; a:255 ) ,
- (name:'lightyellow'; r:255; g:255; b:224; a:255 ) ,
- (name:'lime'; r:0; g:255; b:0; a:255 ) ,
- (name:'limegreen'; r:50; g:205; b:50; a:255 ) ,
- (name:'linen'; r:250; g:240; b:230; a:255 ) ,
- (name:'magenta'; r:255; g:0; b:255; a:255 ) ,
- (name:'maroon'; r:128; g:0; b:0; a:255 ) ,
- (name:'mediumaquamarine'; r:102; g:205; b:170; a:255 ) ,
- (name:'mediumblue'; r:0; g:0; b:205; a:255 ) ,
- (name:'mediumorchid'; r:186; g:85; b:211; a:255 ) ,
- (name:'mediumpurple'; r:147; g:112; b:219; a:255 ) ,
- (name:'mediumseagreen'; r:60; g:179; b:113; a:255 ) ,
- (name:'mediumslateblue'; r:123; g:104; b:238; a:255 ) ,
- (name:'mediumspringgreen'; r:0; g:250; b:154; a:255 ) ,
- (name:'mediumturquoise'; r:72; g:209; b:204; a:255 ) ,
- (name:'mediumvioletred'; r:199; g:21; b:133; a:255 ) ,
- (name:'midnightblue'; r:25; g:25; b:112; a:255 ) ,
- (name:'mintcream'; r:245; g:255; b:250; a:255 ) ,
- (name:'mistyrose'; r:255; g:228; b:225; a:255 ) ,
- (name:'moccasin'; r:255; g:228; b:181; a:255 ) ,
- (name:'navajowhite'; r:255; g:222; b:173; a:255 ) ,
- (name:'navy'; r:0; g:0; b:128; a:255 ) ,
- (name:'oldlace'; r:253; g:245; b:230; a:255 ) ,
- (name:'olive'; r:128; g:128; b:0; a:255 ) ,
- (name:'olivedrab'; r:107; g:142; b:35; a:255 ) ,
- (name:'orange'; r:255; g:165; b:0; a:255 ) ,
- (name:'orangered'; r:255; g:69; b:0; a:255 ) ,
- (name:'orchid'; r:218; g:112; b:214; a:255 ) ,
- (name:'palegoldenrod'; r:238; g:232; b:170; a:255 ) ,
- (name:'palegreen'; r:152; g:251; b:152; a:255 ) ,
- (name:'paleturquoise'; r:175; g:238; b:238; a:255 ) ,
- (name:'palevioletred'; r:219; g:112; b:147; a:255 ) ,
- (name:'papayawhip'; r:255; g:239; b:213; a:255 ) ,
- (name:'peachpuff'; r:255; g:218; b:185; a:255 ) ,
- (name:'peru'; r:205; g:133; b:63; a:255 ) ,
- (name:'pink'; r:255; g:192; b:203; a:255 ) ,
- (name:'plum'; r:221; g:160; b:221; a:255 ) ,
- (name:'powderblue'; r:176; g:224; b:230; a:255 ) ,
- (name:'purple'; r:128; g:0; b:128; a:255 ) ,
- (name:'red'; r:255; g:0; b:0; a:255 ) ,
- (name:'rosybrown'; r:188; g:143; b:143; a:255 ) ,
- (name:'royalblue'; r:65; g:105; b:225; a:255 ) ,
- (name:'saddlebrown'; r:139; g:69; b:19; a:255 ) ,
- (name:'salmon'; r:250; g:128; b:114; a:255 ) ,
- (name:'sandybrown'; r:244; g:164; b:96; a:255 ) ,
- (name:'seagreen'; r:46; g:139; b:87; a:255 ) ,
- (name:'seashell'; r:255; g:245; b:238; a:255 ) ,
- (name:'sienna'; r:160; g:82; b:45; a:255 ) ,
- (name:'silver'; r:192; g:192; b:192; a:255 ) ,
- (name:'skyblue'; r:135; g:206; b:235; a:255 ) ,
- (name:'slateblue'; r:106; g:90; b:205; a:255 ) ,
- (name:'slategray'; r:112; g:128; b:144; a:255 ) ,
- (name:'slategrey'; r:112; g:128; b:144; a:255 ) ,
- (name:'snow'; r:255; g:250; b:250; a:255 ) ,
- (name:'springgreen'; r:0; g:255; b:127; a:255 ) ,
- (name:'steelblue'; r:70; g:130; b:180; a:255 ) ,
- (name:'tan'; r:210; g:180; b:140; a:255 ) ,
- (name:'teal'; r:0; g:128; b:128; a:255 ) ,
- (name:'thistle'; r:216; g:191; b:216; a:255 ) ,
- (name:'tomato'; r:255; g:99; b:71; a:255 ) ,
- (name:'turquoise'; r:64; g:224; b:208; a:255 ) ,
- (name:'violet'; r:238; g:130; b:238; a:255 ) ,
- (name:'wheat'; r:245; g:222; b:179; a:255 ) ,
- (name:'white'; r:255; g:255; b:255; a:255 ) ,
- (name:'whitesmoke'; r:245; g:245; b:245; a:255 ) ,
- (name:'yellow'; r:255; g:255; b:0; a:255 ) ,
- (name:'yellowgreen'; r:154; g:205; b:50; a:255 ) ,
- (name:'zzzzzzzzzzz'; r:0; g:0; b:0; a:0 ) );
-
- pageEqHigh : shortstring =
- #1#2#3#4#5#6#7#8#9#10#11#12#13#14#15#16 +
- #17#18#19#20#21#22#23#24#25#26#27#28#29#30#31#32 +
- #33#34#35#36#37#38#39#40#41#42#43#44#45#46#47#48 +
- #49#50#51#52#53#54#55#56#57#58#59#60#61#62#63#64 +
- #65#66#67#68#69#70#71#72#73#74#75#76#77#78#79#80 +
- #81#82#83#84#85#86#87#88#89#90#91#92#93#94#95#96 +
- #65#66#67#68#69#70#71#72#73#74#75#76#77#78#79#80 +
- #81#82#83#84#85#86#87#88#89#90#123#124#125#126#127#128 +
- #129#130#131#132#133#134#135#136#137#138#139#140#141#142#143#144 +
- #145#146#147#148#149#150#151#152#153#154#155#156#157#158#159#160 +
- #161#162#163#164#165#166#167#168#169#170#171#172#173#174#175#176 +
- #177#178#179#180#181#182#183#184#185#186#187#188#189#190#191#192 +
- #193#194#195#196#197#198#199#200#201#202#203#204#205#206#207#208 +
- #209#210#211#212#213#214#215#216#217#218#219#220#221#222#223#224 +
- #225#226#227#228#229#230#231#232#233#234#235#236#237#238#239#240 +
- #241#242#243#244#245#246#247#248#249#250#251#252#253#254#255;
-
-{ UNIT IMPLEMENTATION }
-{ START_ELEMENT }
-procedure start_element;
-var
- this : parser_ptr;
-
-begin
- this:=parser_ptr(data );
-
- if StrComp(PChar(el ) ,'title' ) = 0 then
- this.m_title_flag:=true
- else
- if StrComp(PChar(el ) ,'g' ) = 0 then
- begin
- this.m_path.push_attr;
- this.parse_attr(attr );
-
- end
- else
- if StrComp(PChar(el ) ,'path' ) = 0 then
- begin
- if this.m_path_flag then
- raise svg_exception.Construct(PChar('start_element: Nested path' ) );
-
- this.m_path.begin_path;
- this.parse_path(attr );
- this.m_path.end_path;
-
- this.m_path_flag:=true;
-
- end
- else
- if StrComp(PChar(el ) ,'rect' ) = 0 then
- this.parse_rect(attr )
- else
- if StrComp(PChar(el ) ,'line' ) = 0 then
- this.parse_line(attr )
- else
- if StrComp(PChar(el ) ,'polyline' ) = 0 then
- this.parse_poly(attr ,false )
- else
- if StrComp(PChar(el ) ,'polygon' ) = 0 then
- this.parse_poly(attr ,true );
-
- //else
- // if StrComp(PChar(el ) ,'<OTHER_ELEMENTS>' ) = 0 then
- // begin
- // end
- //...
-
-end;
-
-{ END_ELEMENT }
-procedure end_element;
-var
- this : parser_ptr;
-
-begin
- this:=parser_ptr(data );
-
- if StrComp(PChar(el ) ,'title' ) = 0 then
- this.m_title_flag:=false
- else
- if StrComp(PChar(el ) ,'g' ) = 0 then
- this.m_path.pop_attr
- else
- if StrComp(PChar(el ) ,'path' ) = 0 then
- this.m_path_flag:=false;
-
- //else
- // if StrComp(PChar(el ) ,'<OTHER_ELEMENTS>' ) = 0 then
- // begin
- // end
- // ...
-
-end;
-
-{ CONTENT }
-procedure content;
-var
- this : parser_ptr;
-
-begin
- this:=parser_ptr(data );
-
-// m_title_flag signals that the <title> tag is being parsed now.
-// The following code concatenates the pieces of content of the <title> tag.
- if this.m_title_flag then
- begin
- if len + this.m_title_len > 255 then
- len:=255 - this.m_title_len;
-
- if len > 0 then
- begin
- move(
- s^ ,
- char_ptr(ptrcomp(this.m_title ) + this.m_title_len )^ ,
- len );
-
- inc(this.m_title_len ,len );
-
- char_ptr(ptrcomp(this.m_title ) + this.m_title_len )^:=#0;
-
- end;
-
- end;
-
-end;
-
-{ hex_unsigned }
-function hex_unsigned(hexstr : agg_basics.char_ptr ) : unsigned;
-
-function xyint(x ,y : integer ) : integer;
-var
- f : integer;
- m : boolean;
-
-begin
- m:=false;
-
- if y < 0 then
- begin
- y:=y * -1;
- m:=true;
-
- end;
-
- result:=x;
-
- if y > 1 then
- for f:=1 to y - 1 do
- result:=result * x;
-
- if m then
- result:=result * -1;
-
-end;
-
-var
- h : shortstring;
- fcb : byte;
- yps ,
- mul ,
- num : unsigned;
-
-label
- Err ,Esc ;
-
-const
- hex : string[16 ] = '0123456789ABCDEF';
-
-begin
- h:='';
-
- while hexstr^ <> #0 do
- begin
- h:=h + pageEqHigh[byte(hexstr^ ) ];
-
- inc(ptrcomp(hexstr ) );
-
- end;
-
- if length(h ) > 0 then
- begin
- case h[length(h ) ] of
- '0'..'9' ,'A'..'F' :
- else
- goto Err;
-
- end;
-
- num:=pos(h[length(h ) ] ,hex ) - 1;
- yps:=2;
- mul:=xyint(4 ,yps );
-
- if length(h ) > 1 then
- for fcb:=length(h ) - 1 downto 1 do
- begin
- case h[fcb ] of
- '0'..'9' ,'A'..'F' :
- else
- goto Err;
-
- end;
-
- inc(num ,(pos(h[fcb ] ,hex ) - 1 ) * mul );
- inc(yps ,2 );
-
- mul:=xyint(4 ,yps );
-
- end;
-
- goto Esc;
-
- end;
-
-Err:
- num:=0;
-
-Esc:
- result:=num;
-
-end;
-
-{ parse_color }
-function parse_color(str : agg_basics.char_ptr ) : aggclr;
-var
- u : unsigned;
- p : named_color_ptr;
- m : shortstring;
-
-begin
- while str^ = ' ' do
- inc(ptrcomp(str ) );
-
- if str^ = '#' then
- begin
- inc(ptrcomp(str ) );
-
- u:=hex_unsigned(str );
-
- result.Construct(rgb8_packed(u ) );
-
- end
- else
- begin
- p:=NIL;
-
- for u:=0 to colors_num - 1 do
- if StrComp(colors[u ].name ,PChar(str ) ) = 0 then
- begin
- p:=@colors[u ];
-
- break;
-
- end;
-
- if p = NIL then
- begin
- m:='parse_color: Invalid color name ' + StrPas(PChar(str ) ) + #0;
-
- raise svg_exception.Construct(PChar(@m[1 ] ) );
-
- end;
-
- result.ConstrInt(p.r ,p.g ,p.b ,p.a );
-
- end;
-
-end;
-
-{ parse_double }
-function parse_double(str : agg_basics.char_ptr ) : double;
-begin
- while str^ = ' ' do
- inc(ptrcomp(str ) );
-
- result:=get_double(pointer(PChar(str ) ) );
-
-end;
-
-{ islower }
-function islower(ch : char ) : boolean;
-begin
- case ch of
- #97..#122 :
- result:=true;
-
- else
- result:=false;
-
- end;
-
-end;
-
-{ is_numeric }
-function is_numeric(ch : char ) : boolean;
-begin
- result:=Pos(ch ,'0123456789+-.eE' ) <> 0;
-
-end;
-
-{ parse_transform_args }
-function parse_transform_args(str : agg_basics.char_ptr; args : double_ptr; max_na : unsigned; na : unsigned_ptr ) : unsigned;
-var
- ptr ,end_ : agg_basics.char_ptr;
-
-begin
- na^:=0;
- ptr:=str;
-
- while (ptr^ <> #0 ) and
- (ptr^ <> '(' ) do
- inc(ptrcomp(ptr ) );
-
- if ptr^ = #0 then
- raise svg_exception.Construct(PChar('parse_transform_args: Invalid syntax' ) );
-
- end_:=ptr;
-
- while (end_^ <> #0 ) and
- (end_^ <> ')' ) do
- inc(ptrcomp(end_ ) );
-
- if end_^ = #0 then
- raise svg_exception.Construct(PChar('parse_transform_args: Invalid syntax' ) );
-
- while ptrcomp(ptr ) < ptrcomp(end_ ) do
- if is_numeric(ptr^ ) then
- begin
- if na^ >= max_na then
- raise svg_exception.Construct(PChar('parse_transform_args: Too many arguments' ) );
-
- double_ptr(ptrcomp(args ) + na^ * sizeof(double ) )^:=get_double(ptr );
-
- inc(na^ );
-
- while (ptrcomp(ptr ) < ptrcomp(end_ ) ) and
- is_numeric(ptr^ ) do
- inc(ptrcomp(ptr ) );
-
- end
- else
- inc(ptrcomp(ptr ) );
-
- result:=unsigned(ptrcomp(end_ ) - ptrcomp(str ) );
-
-end;
-
-{ CONSTRUCT }
-constructor parser.Construct;
-begin
- m_path:=path;
-
- m_tokenizer.Construct;
-
- agg_getmem(pointer(m_buf ) ,buf_size );
- agg_getmem(pointer(m_title ) ,256 );
-
- m_title_len :=0;
- m_title_flag:=false;
- m_path_flag :=false;
-
- m_attr_name_aloc :=128;
- m_attr_value_aloc:=1024;
-
- agg_getmem(pointer(m_attr_name ) ,m_attr_name_aloc );
- agg_getmem(pointer(m_attr_value ) ,m_attr_value_aloc );
-
- m_attr_name_len :=127;
- m_attr_value_len:=1023;
-
- m_title^:=#0;
-
-end;
-
-{ DESTRUCT }
-destructor parser.Destruct;
-begin
- agg_freemem(pointer(m_attr_value ) ,m_attr_value_aloc );
- agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc );
- agg_freemem(pointer(m_title ) ,256 );
- agg_freemem(pointer(m_buf ) ,buf_size );
-
-end;
-
-{ PARSE }
-procedure parser.parse;
-var
- msg : array[0..1023 ] of char;
-
- p : XML_Parser;
- af : api_file;
- ts : char_ptr;
-
- done : boolean;
- len : int;
-
-begin
- p:=XML_ParserCreate(NIL );
-
- if p = NIL then
- raise svg_exception.Construct(PChar('Couldn''t allocate memory for parser' ) );
-
- XML_SetUserData (p ,@self );
- XML_SetElementHandler (p ,@start_element ,@end_element );
- XML_SetCharacterDataHandler(p ,@content );
-
- fname:=fname + #0;
-
- dec(byte(fname[0 ] ) );
-
- if not api_open_file(af ,fname ) then
- begin
- sprintf(@msg[0 ] ,'Couldn''t open file %s' ,unsigned(@fname[1 ] ) );
-
- XML_ParserFree(p );
-
- raise svg_exception.Construct(PChar(@msg[0 ] ) );
-
- end;
-
- done:=false;
-
- repeat
- api_read_file(af ,m_buf ,buf_size ,len );
-
- done:=len < buf_size;
-
- if XML_Parse(p ,pointer(m_buf ) ,len ,int(done ) ) = XML_STATUS_ERROR then
- begin
- api_close_file(af );
- XML_ParserFree(p );
-
- sprintf(
- @msg[0 ] ,
- '%s at line ' ,
- unsigned(
- XML_ErrorString(
- int(XML_GetErrorCode(p ) ) ) ) );
-
- sprintf(
- @msg[StrLen(msg ) ] ,
- '%d'#13 ,
- XML_GetCurrentLineNumber(p ) );
-
- raise svg_exception.Construct(PChar(@msg[0 ] ) );
-
- end;
-
- until done;
-
- api_close_file(af );
- XML_ParserFree(p );
-
- ts:=m_title;
-
- while ts^ <> #0 do
- begin
- if byte(ts^ ) < byte(' ' ) then
- ts^:=' ';
-
- inc(ptrcomp(ts ) );
-
- end;
-
-end;
-
-{ TITLE }
-function parser.title;
-begin
- result:=m_title;
-
-end;
-
-{ PARSE_ATTR }
-procedure parser.parse_attr(attr : char_ptr_ptr );
-var
- i : int;
-
-begin
- i:=0;
-
- while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
- begin
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'style' ) = 0 then
- parse_style(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ )
- else
- parse_attr(
- agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ,
- agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- inc(i ,2 );
-
- end;
-
-end;
-
-{ PARSE_PATH }
-procedure parser.parse_path;
-var
- i : int;
-
- tmp : array[0..3 ] of agg_basics.char_ptr;
-
-begin
- i:=0;
-
- while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
- begin
- // The <path> tag can consist of the path itself ("d=")
- // as well as of other parameters like "style=", "transform=", etc.
- // In the last case we simply rely on the function of parsing
- // attributes (see 'else' branch).
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'d' ) = 0 then
- begin
- m_tokenizer.set_path_str(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- m_path.parse_path(@m_tokenizer );
-
- end
- else
- begin
- // Create a temporary single pair "name-value" in order
- // to avoid multiple calls for the same attribute.
- tmp[0 ]:=agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^;
- tmp[1 ]:=agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^;
- tmp[2 ]:=NIL;
- tmp[3 ]:=NIL;
-
- parse_attr(@tmp );
-
- end;
-
- inc(i ,2 );
-
- end;
-
-end;
-
-{ PARSE_POLY }
-procedure parser.parse_poly;
-var
- i : int;
-
- x ,y : double;
-
-begin
- x:=0.0;
- y:=0.0;
-
- m_path.begin_path;
-
- i:=0;
-
- while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
- begin
- if not parse_attr(
- agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ,
- agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then
- if StrComp(PChar(agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'points' ) = 0 then
- begin
- m_tokenizer.set_path_str(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- if not m_tokenizer.next then
- raise svg_exception.Construct(PChar('parse_poly: Too few coordinates' ) );
-
- x:=m_tokenizer.last_number;
-
- if not m_tokenizer.next then
- raise svg_exception.Construct(PChar('parse_poly: Too few coordinates' ) );
-
- y:=m_tokenizer.last_number;
-
- m_path.move_to(x ,y );
-
- while m_tokenizer.next do
- begin
- x:=m_tokenizer.last_number;
-
- if not m_tokenizer.next then
- raise svg_exception.Construct(PChar('parse_poly: Odd number of coordinates' ) );
-
- y:=m_tokenizer.last_number;
-
- m_path.line_to(x ,y );
-
- end;
-
- end;
-
- inc(i ,2 );
-
- end;
-
- m_path.end_path;
-
-end;
-
-{ PARSE_RECT }
-procedure parser.parse_rect;
-var
- i : int;
-
- x ,y ,w ,h : double;
-
-begin
- x:=0.0;
- y:=0.0;
- w:=0.0;
- h:=0.0;
-
- m_path.begin_path;
-
- i:=0;
-
- while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
- begin
- if not parse_attr(
- agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ,
- agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then
- begin
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x' ) = 0 then
- x:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y' ) = 0 then
- y:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'width' ) = 0 then
- w:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'height' ) = 0 then
- h:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- // rx - to be implemented
- // ry - to be implemented
-
- end;
-
- inc(i ,2 );
-
- end;
-
- if (w <> 0.0 ) and
- (h <> 0.0 ) then
- begin
- if w < 0.0 then
- raise svg_exception.Construct(PChar('parse_rect: Invalid width: ' ) );
-
- if h < 0.0 then
- raise svg_exception.Construct(PChar('parse_rect: Invalid height: ' ) );
-
- m_path.move_to(x ,y );
- m_path.line_to(x + w ,y );
- m_path.line_to(x + w ,y + h );
- m_path.line_to(x ,y + h );
- m_path.close_subpath;
-
- end;
-
- m_path.end_path;
-
-end;
-
-{ PARSE_LINE }
-procedure parser.parse_line;
-var
- i : int;
-
- x1 ,y1 ,x2 ,y2 : double;
-
-begin
- x1:=0.0;
- y1:=0.0;
- x2:=0.0;
- y2:=0.0;
-
- m_path.begin_path;
-
- i:=0;
-
- while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
- begin
- if not parse_attr(
- agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ,
- agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then
- begin
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x1' ) = 0 then
- x1:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y1' ) = 0 then
- y1:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x2' ) = 0 then
- x2:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y2' ) = 0 then
- y2:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
-
- end;
-
- inc(i ,2 );
-
- end;
-
- m_path.move_to(x1 ,y1 );
- m_path.line_to(x2 ,y2 );
- m_path.end_path;
-
-end;
-
-{ PARSE_STYLE }
-procedure parser.parse_style;
-var
- nv_start ,nv_end : agg_basics.char_ptr;
-
-begin
- while str^ <> #0 do
- begin
- // Left Trim
- while (str^ <> #0 ) and
- (str^ = ' ' ) do
- inc(ptrcomp(str ) );
-
- nv_start:=str;
-
- while (str^ <> #0 ) and
- (str^ <> ';' ) do
- inc(ptrcomp(str ) );
-
- nv_end:=str;
-
- // Right Trim
- while (ptrcomp(nv_end ) > ptrcomp(nv_start ) ) and
- ((nv_end^ = ';' ) or
- (nv_end^ = ' ' ) ) do
- dec(ptrcomp(nv_end ) );
-
- inc(ptrcomp(nv_end ) );
-
- parse_name_value(nv_start ,nv_end );
-
- if str^ <> #0 then
- inc(ptrcomp(str ) );
-
- end;
-
-end;
-
-{ PARSE_TRANSFORM }
-procedure parser.parse_transform;
-begin
- while str^ <> #0 do
- begin
- if islower(str^ ) then
- if StrLComp(PChar(str ) ,'matrix' ,6 ) = 0 then
- inc(ptrcomp(str ) ,parse_matrix(str ) )
- else
- if StrLComp(PChar(str ) ,'translate' ,9 ) = 0 then
- inc(ptrcomp(str ) ,parse_translate(str ) )
- else
- if StrLComp(PChar(str ) ,'rotate' ,6 ) = 0 then
- inc(ptrcomp(str ) ,parse_rotate(str ) )
- else
- if StrLComp(PChar(str ) ,'scale' ,5 ) = 0 then
- inc(ptrcomp(str ) ,parse_scale(str ) )
- else
- if StrLComp(PChar(str ) ,'skewX' ,5 ) = 0 then
- inc(ptrcomp(str ) ,parse_skew_x(str ) )
- else
- if StrLComp(PChar(str ) ,'skewY' ,5 ) = 0 then
- inc(ptrcomp(str ) ,parse_skew_y(str ) )
- else
- inc(ptrcomp(str ) )
-
- else
- inc(ptrcomp(str ) );
-
- end;
-
-end;
-
-{ PARSE_MATRIX }
-function parser.parse_matrix;
-var
- args : array[0..5 ] of double;
-
- na ,len : unsigned;
-
- ta : trans_affine;
-
-begin
- na :=0;
- len:=parse_transform_args(str ,@args ,6 ,@na );
-
- if na <> 6 then
- raise svg_exception.Construct(PChar('parse_matrix: Invalid number of arguments' ) );
-
- ta.Construct(args[0 ] ,args[1 ] ,args[2 ] ,args[3 ] ,args[4 ] ,args[5 ] );
-
- m_path.transform.premultiply(@ta );
-
- result:=len;
-
-end;
-
-{ PARSE_TRANSLATE }
-function parser.parse_translate;
-var
- args : array[0..1 ] of double;
-
- na ,len : unsigned;
-
- tat : trans_affine_translation;
-
-begin
- na :=0;
- len:=parse_transform_args(str ,@args ,2 ,@na );
-
- if na = 1 then
- args[1 ]:=0.0;
-
- tat.Construct(args[0 ] ,args[1 ] );
-
- m_path.transform.premultiply(@tat );
-
- result:=len;
-
-end;
-
-{ PARSE_ROTATE }
-function parser.parse_rotate;
-var
- args : array[0..2 ] of double;
-
- na ,len : unsigned;
-
- tar : trans_affine_rotation;
-
- tat ,t : trans_affine_translation;
-
-begin
- na :=0;
- len:=parse_transform_args(str ,@args ,3 ,@na );
-
- if na = 1 then
- begin
- tar.Construct(deg2rad(args[0 ] ) );
-
- m_path.transform.premultiply(@tar );
-
- end
- else
- if na = 3 then
- begin
- t.Construct(-args[1 ] ,-args[2 ] );
-
- tar.Construct(deg2rad(args[0 ] ) );
- tat.Construct(args[1 ] ,args[2 ] );
-
- t.multiply(@tar );
- t.multiply(@tat );
-
- m_path.transform.premultiply(@t );
-
- end
- else
- raise svg_exception.Construct(PChar('parse_rotate: Invalid number of arguments' ) );
-
- result:=len;
-
-end;
-
-{ PARSE_SCALE }
-function parser.parse_scale;
-var
- args : array[0..1 ] of double;
-
- na ,len : unsigned;
-
- tas : trans_affine_scaling;
-
-begin
- na :=0;
- len:=parse_transform_args(str ,@args ,2 ,@na );
-
- if na = 1 then
- args[1 ]:=args[0 ];
-
- tas.Construct(args[0 ] ,args[1 ] );
-
- m_path.transform.premultiply(@tas );
-
- result:=len;
-
-end;
-
-{ PARSE_SKEW_X }
-function parser.parse_skew_x;
-var
- arg : double;
-
- na ,len : unsigned;
-
- tas : trans_affine_skewing;
-
-begin
- na :=0;
- len:=parse_transform_args(str ,@arg ,1 ,@na );
-
- tas.Construct(deg2rad(arg ) ,0.0 );
-
- m_path.transform.premultiply(@tas );
-
- result:=len;
-
-end;
-
-{ PARSE_SKEW_Y }
-function parser.parse_skew_y;
-var
- arg : double;
-
- na ,len : unsigned;
-
- tas : trans_affine_skewing;
-
-begin
- na :=0;
- len:=parse_transform_args(str ,@arg ,1 ,@na );
-
- tas.Construct(0.0 ,deg2rad(arg ) );
-
- m_path.transform.premultiply(@tas );
-
- result:=len;
-
-end;
-
-{ PARSE_ATTR }
-function parser.parse_attr(name ,value : agg_basics.char_ptr ) : boolean;
-var
- clr : aggclr;
-
-begin
- result:=true;
-
- if StrComp(PChar(name ) ,'style' ) = 0 then
- parse_style(value )
- else
- if StrComp(PChar(name ) ,'fill' ) = 0 then
- if StrComp(PChar(value ) ,'none' ) = 0 then
- m_path.fill_none
- else
- begin
- clr:=parse_color(value );
-
- m_path.fill(@clr );
-
- end
- else
- if StrComp(PChar(name ) ,'fill-opacity' ) = 0 then
- m_path.fill_opacity(parse_double(value ) )
- else
- if StrComp(PChar(name ) ,'stroke' ) = 0 then
- if StrComp(PChar(value ) ,'none' ) = 0 then
- m_path.stroke_none
- else
- begin
- clr:=parse_color(value );
-
- m_path.stroke(@clr );
-
- end
- else
- if StrComp(PChar(name ) ,'stroke-width' ) = 0 then
- m_path.stroke_width(parse_double(value ) )
- else
- if StrComp(PChar(name ) ,'stroke-linecap' ) = 0 then
- begin
- if StrComp(PChar(value ) ,'butt' ) = 0 then
- m_path.line_cap(butt_cap )
- else
- if StrComp(PChar(value ) ,'round' ) = 0 then
- m_path.line_cap(round_cap )
- else
- if StrComp(PChar(value ) ,'square' ) = 0 then
- m_path.line_cap(square_cap );
-
- end
- else
- if StrComp(PChar(name ) ,'stroke-linejoin' ) = 0 then
- begin
- if StrComp(PChar(value ) ,'miter' ) = 0 then
- m_path.line_join(miter_join )
- else
- if StrComp(PChar(value ) ,'round' ) = 0 then
- m_path.line_join(round_join )
- else
- if StrComp(PChar(value ) ,'bevel' ) = 0 then
- m_path.line_join(bevel_join );
-
- end
- else
- if StrComp(PChar(name ) ,'stroke-miterlimit' ) = 0 then
- m_path.miter_limit(parse_double(value ) )
- else
- if StrComp(PChar(name ) ,'stroke-opacity' ) = 0 then
- m_path.stroke_opacity(parse_double(value ) )
- else
- if StrComp(PChar(name ) ,'transform' ) = 0 then
- parse_transform(value )
-
- //else
- // if StrComp(PChar(el ) ,'<OTHER_ATTRIBUTES>' ) = 0 then
- // begin
- // end
- // ...
-
- else
- result:=false;
-
-end;
-
-{ PARSE_NAME_VALUE }
-function parser.parse_name_value;
-var
- str ,val : agg_basics.char_ptr;
-
-begin
- str:=nv_start;
-
- while (ptrcomp(str ) < ptrcomp(nv_end ) ) and
- (str^ <> ':' ) do
- inc(ptrcomp(str ) );
-
- val:=str;
-
-// Right Trim
- while (ptrcomp(str ) > ptrcomp(nv_start ) ) and
- ((str^ = ':' ) or
- (str^ = ' ' ) ) do
- dec(ptrcomp(str ) );
-
- inc(ptrcomp(str ) );
-
- copy_name(nv_start ,str );
-
- while (ptrcomp(val ) < ptrcomp(nv_end ) ) and
- ((val^ = ':' ) or
- (val^ = ' ' ) ) do
- inc(ptrcomp(val ) );
-
- copy_value(val ,nv_end );
-
- result:=parse_attr(agg_basics.char_ptr(m_attr_name ) ,agg_basics.char_ptr(m_attr_value ) );
-
-end;
-
-{ COPY_NAME }
-procedure parser.copy_name;
-var
- len : unsigned;
-
-begin
- len:=ptrcomp(end_ ) - ptrcomp(start );
-
- if (m_attr_name_len = 0 ) or
- (len > m_attr_name_len ) then
- begin
- agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc );
-
- m_attr_name_aloc:=len + 1;
-
- agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc );
-
- m_attr_name_len:=len;
-
- end;
-
- if len <> 0 then
- move(start^ ,m_attr_name^ ,len );
-
- char_ptr(ptrcomp(m_attr_name ) + len )^:=#0;
-
-end;
-
-{ COPY_VALUE }
-procedure parser.copy_value;
-var
- len : unsigned;
-
-begin
- len:=ptrcomp(end_ ) - ptrcomp(start );
-
- if (m_attr_value_len = 0 ) or
- (len > m_attr_value_len ) then
- begin
- agg_freemem(pointer(m_attr_value ) ,m_attr_value_aloc );
-
- m_attr_value_aloc:=len + 1;
-
- agg_getmem(pointer(m_attr_value ) ,m_attr_value_aloc );
-
- m_attr_value_len:=len;
-
- end;
-
- if len <> 0 then
- move(start^ ,m_attr_value^ ,len );
-
- char_ptr(ptrcomp(m_attr_value ) + len )^:=#0;
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 03.01.2007-Milano: Adjustments for ExpatWrap (Win,Linux & Mac) +// 23.06.2006-Milano: ptrcomp adjustments +// 24.04.2006-Milano: Unit port establishment +// +{ agg_svg_parser.pas } +unit + agg_svg_parser ; + +INTERFACE + +{$DEFINE EXPAT_WRAPPER } +{$I agg_mode.inc } + +uses + SysUtils , + agg_basics , + agg_color , + agg_svg_path_tokenizer , + agg_svg_path_renderer , + agg_svg_exception , + agg_trans_affine , + agg_math_stroke , + expat , + file_utils_ ; + +{ TYPES DEFINITION } +const + buf_size = 512; + +type + parser_ptr = ^parser; + parser = object + m_path : path_renderer_ptr; + m_tokenizer : path_tokenizer; + + m_buf , + m_title : char_ptr; + + m_title_len : unsigned; + m_title_flag , + m_path_flag : boolean; + m_attr_name , + m_attr_value : char_ptr; + + m_attr_name_len , + m_attr_name_aloc , + m_attr_value_len , + m_attr_value_aloc : unsigned; + + constructor Construct(path : path_renderer_ptr ); + destructor Destruct; + + procedure parse(fname : shortstring ); + function title : char_ptr; + + // XML event handlers + procedure parse_attr (attr : char_ptr_ptr ); overload; + procedure parse_path (attr : char_ptr_ptr ); + procedure parse_poly (attr : char_ptr_ptr; close_flag : boolean ); + procedure parse_rect (attr : char_ptr_ptr ); + procedure parse_line (attr : char_ptr_ptr ); + procedure parse_style (str : agg_basics.char_ptr ); + procedure parse_transform(str : agg_basics.char_ptr ); + + function parse_matrix (str : agg_basics.char_ptr ) : unsigned; + function parse_translate(str : agg_basics.char_ptr ) : unsigned; + function parse_rotate (str : agg_basics.char_ptr ) : unsigned; + function parse_scale (str : agg_basics.char_ptr ) : unsigned; + function parse_skew_x (str : agg_basics.char_ptr ) : unsigned; + function parse_skew_y (str : agg_basics.char_ptr ) : unsigned; + + function parse_attr (name ,value : agg_basics.char_ptr ) : boolean; overload; + function parse_name_value(nv_start ,nv_end : agg_basics.char_ptr ) : boolean; + + procedure copy_name (start ,end_ : agg_basics.char_ptr ); + procedure copy_value(start ,end_ : agg_basics.char_ptr ); + + end; + +{ GLOBAL PROCEDURES } + procedure start_element(data : pointer; el : char_ptr; attr : char_ptr_ptr ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF } + procedure end_element (data : pointer; el : char_ptr ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF } + procedure content (data : pointer; s : char_ptr; len : int ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +type + named_color_ptr = ^named_color; + named_color = record + name : array[0..21 ] of char; + + r ,g ,b ,a : int8u; + + end; + +const + colors_num = 148; + + colors : array[0..colors_num - 1 ] of named_color = + ((name:'aliceblue'; r:240; g:248; b:255; a:255 ) , + (name:'antiquewhite'; r:250; g:235; b:215; a:255 ) , + (name:'aqua'; r:0; g:255; b:255; a:255 ) , + (name:'aquamarine'; r:127; g:255; b:212; a:255 ) , + (name:'azure'; r:240; g:255; b:255; a:255 ) , + (name:'beige'; r:245; g:245; b:220; a:255 ) , + (name:'bisque'; r:255; g:228; b:196; a:255 ) , + (name:'black'; r:0; g:0; b:0; a:255 ) , + (name:'blanchedalmond'; r:255; g:235; b:205; a:255 ) , + (name:'blue'; r:0; g:0; b:255; a:255 ) , + (name:'blueviolet'; r:138; g:43; b:226; a:255 ) , + (name:'brown'; r:165; g:42; b:42; a:255 ) , + (name:'burlywood'; r:222; g:184; b:135; a:255 ) , + (name:'cadetblue'; r:95; g:158; b:160; a:255 ) , + (name:'chartreuse'; r:127; g:255; b:0; a:255 ) , + (name:'chocolate'; r:210; g:105; b:30; a:255 ) , + (name:'coral'; r:255; g:127; b:80; a:255 ) , + (name:'cornflowerblue'; r:100; g:149; b:237; a:255 ) , + (name:'cornsilk'; r:255; g:248; b:220; a:255 ) , + (name:'crimson'; r:220; g:20; b:60; a:255 ) , + (name:'cyan'; r:0; g:255; b:255; a:255 ) , + (name:'darkblue'; r:0; g:0; b:139; a:255 ) , + (name:'darkcyan'; r:0; g:139; b:139; a:255 ) , + (name:'darkgoldenrod'; r:184; g:134; b:11; a:255 ) , + (name:'darkgray'; r:169; g:169; b:169; a:255 ) , + (name:'darkgreen'; r:0; g:100; b:0; a:255 ) , + (name:'darkgrey'; r:169; g:169; b:169; a:255 ) , + (name:'darkkhaki'; r:189; g:183; b:107; a:255 ) , + (name:'darkmagenta'; r:139; g:0; b:139; a:255 ) , + (name:'darkolivegreen'; r:85; g:107; b:47; a:255 ) , + (name:'darkorange'; r:255; g:140; b:0; a:255 ) , + (name:'darkorchid'; r:153; g:50; b:204; a:255 ) , + (name:'darkred'; r:139; g:0; b:0; a:255 ) , + (name:'darksalmon'; r:233; g:150; b:122; a:255 ) , + (name:'darkseagreen'; r:143; g:188; b:143; a:255 ) , + (name:'darkslateblue'; r:72; g:61; b:139; a:255 ) , + (name:'darkslategray'; r:47; g:79; b:79; a:255 ) , + (name:'darkslategrey'; r:47; g:79; b:79; a:255 ) , + (name:'darkturquoise'; r:0; g:206; b:209; a:255 ) , + (name:'darkviolet'; r:148; g:0; b:211; a:255 ) , + (name:'deeppink'; r:255; g:20; b:147; a:255 ) , + (name:'deepskyblue'; r:0; g:191; b:255; a:255 ) , + (name:'dimgray'; r:105; g:105; b:105; a:255 ) , + (name:'dimgrey'; r:105; g:105; b:105; a:255 ) , + (name:'dodgerblue'; r:30; g:144; b:255; a:255 ) , + (name:'firebrick'; r:178; g:34; b:34; a:255 ) , + (name:'floralwhite'; r:255; g:250; b:240; a:255 ) , + (name:'forestgreen'; r:34; g:139; b:34; a:255 ) , + (name:'fuchsia'; r:255; g:0; b:255; a:255 ) , + (name:'gainsboro'; r:220; g:220; b:220; a:255 ) , + (name:'ghostwhite'; r:248; g:248; b:255; a:255 ) , + (name:'gold'; r:255; g:215; b:0; a:255 ) , + (name:'goldenrod'; r:218; g:165; b:32; a:255 ) , + (name:'gray'; r:128; g:128; b:128; a:255 ) , + (name:'green'; r:0; g:128; b:0; a:255 ) , + (name:'greenyellow'; r:173; g:255; b:47; a:255 ) , + (name:'grey'; r:128; g:128; b:128; a:255 ) , + (name:'honeydew'; r:240; g:255; b:240; a:255 ) , + (name:'hotpink'; r:255; g:105; b:180; a:255 ) , + (name:'indianred'; r:205; g:92; b:92; a:255 ) , + (name:'indigo'; r:75; g:0; b:130; a:255 ) , + (name:'ivory'; r:255; g:255; b:240; a:255 ) , + (name:'khaki'; r:240; g:230; b:140; a:255 ) , + (name:'lavender'; r:230; g:230; b:250; a:255 ) , + (name:'lavenderblush'; r:255; g:240; b:245; a:255 ) , + (name:'lawngreen'; r:124; g:252; b:0; a:255 ) , + (name:'lemonchiffon'; r:255; g:250; b:205; a:255 ) , + (name:'lightblue'; r:173; g:216; b:230; a:255 ) , + (name:'lightcoral'; r:240; g:128; b:128; a:255 ) , + (name:'lightcyan'; r:224; g:255; b:255; a:255 ) , + (name:'lightgoldenrodyellow'; r:250; g:250; b:210; a:255 ) , + (name:'lightgray'; r:211; g:211; b:211; a:255 ) , + (name:'lightgreen'; r:144; g:238; b:144; a:255 ) , + (name:'lightgrey'; r:211; g:211; b:211; a:255 ) , + (name:'lightpink'; r:255; g:182; b:193; a:255 ) , + (name:'lightsalmon'; r:255; g:160; b:122; a:255 ) , + (name:'lightseagreen'; r:32; g:178; b:170; a:255 ) , + (name:'lightskyblue'; r:135; g:206; b:250; a:255 ) , + (name:'lightslategray'; r:119; g:136; b:153; a:255 ) , + (name:'lightslategrey'; r:119; g:136; b:153; a:255 ) , + (name:'lightsteelblue'; r:176; g:196; b:222; a:255 ) , + (name:'lightyellow'; r:255; g:255; b:224; a:255 ) , + (name:'lime'; r:0; g:255; b:0; a:255 ) , + (name:'limegreen'; r:50; g:205; b:50; a:255 ) , + (name:'linen'; r:250; g:240; b:230; a:255 ) , + (name:'magenta'; r:255; g:0; b:255; a:255 ) , + (name:'maroon'; r:128; g:0; b:0; a:255 ) , + (name:'mediumaquamarine'; r:102; g:205; b:170; a:255 ) , + (name:'mediumblue'; r:0; g:0; b:205; a:255 ) , + (name:'mediumorchid'; r:186; g:85; b:211; a:255 ) , + (name:'mediumpurple'; r:147; g:112; b:219; a:255 ) , + (name:'mediumseagreen'; r:60; g:179; b:113; a:255 ) , + (name:'mediumslateblue'; r:123; g:104; b:238; a:255 ) , + (name:'mediumspringgreen'; r:0; g:250; b:154; a:255 ) , + (name:'mediumturquoise'; r:72; g:209; b:204; a:255 ) , + (name:'mediumvioletred'; r:199; g:21; b:133; a:255 ) , + (name:'midnightblue'; r:25; g:25; b:112; a:255 ) , + (name:'mintcream'; r:245; g:255; b:250; a:255 ) , + (name:'mistyrose'; r:255; g:228; b:225; a:255 ) , + (name:'moccasin'; r:255; g:228; b:181; a:255 ) , + (name:'navajowhite'; r:255; g:222; b:173; a:255 ) , + (name:'navy'; r:0; g:0; b:128; a:255 ) , + (name:'oldlace'; r:253; g:245; b:230; a:255 ) , + (name:'olive'; r:128; g:128; b:0; a:255 ) , + (name:'olivedrab'; r:107; g:142; b:35; a:255 ) , + (name:'orange'; r:255; g:165; b:0; a:255 ) , + (name:'orangered'; r:255; g:69; b:0; a:255 ) , + (name:'orchid'; r:218; g:112; b:214; a:255 ) , + (name:'palegoldenrod'; r:238; g:232; b:170; a:255 ) , + (name:'palegreen'; r:152; g:251; b:152; a:255 ) , + (name:'paleturquoise'; r:175; g:238; b:238; a:255 ) , + (name:'palevioletred'; r:219; g:112; b:147; a:255 ) , + (name:'papayawhip'; r:255; g:239; b:213; a:255 ) , + (name:'peachpuff'; r:255; g:218; b:185; a:255 ) , + (name:'peru'; r:205; g:133; b:63; a:255 ) , + (name:'pink'; r:255; g:192; b:203; a:255 ) , + (name:'plum'; r:221; g:160; b:221; a:255 ) , + (name:'powderblue'; r:176; g:224; b:230; a:255 ) , + (name:'purple'; r:128; g:0; b:128; a:255 ) , + (name:'red'; r:255; g:0; b:0; a:255 ) , + (name:'rosybrown'; r:188; g:143; b:143; a:255 ) , + (name:'royalblue'; r:65; g:105; b:225; a:255 ) , + (name:'saddlebrown'; r:139; g:69; b:19; a:255 ) , + (name:'salmon'; r:250; g:128; b:114; a:255 ) , + (name:'sandybrown'; r:244; g:164; b:96; a:255 ) , + (name:'seagreen'; r:46; g:139; b:87; a:255 ) , + (name:'seashell'; r:255; g:245; b:238; a:255 ) , + (name:'sienna'; r:160; g:82; b:45; a:255 ) , + (name:'silver'; r:192; g:192; b:192; a:255 ) , + (name:'skyblue'; r:135; g:206; b:235; a:255 ) , + (name:'slateblue'; r:106; g:90; b:205; a:255 ) , + (name:'slategray'; r:112; g:128; b:144; a:255 ) , + (name:'slategrey'; r:112; g:128; b:144; a:255 ) , + (name:'snow'; r:255; g:250; b:250; a:255 ) , + (name:'springgreen'; r:0; g:255; b:127; a:255 ) , + (name:'steelblue'; r:70; g:130; b:180; a:255 ) , + (name:'tan'; r:210; g:180; b:140; a:255 ) , + (name:'teal'; r:0; g:128; b:128; a:255 ) , + (name:'thistle'; r:216; g:191; b:216; a:255 ) , + (name:'tomato'; r:255; g:99; b:71; a:255 ) , + (name:'turquoise'; r:64; g:224; b:208; a:255 ) , + (name:'violet'; r:238; g:130; b:238; a:255 ) , + (name:'wheat'; r:245; g:222; b:179; a:255 ) , + (name:'white'; r:255; g:255; b:255; a:255 ) , + (name:'whitesmoke'; r:245; g:245; b:245; a:255 ) , + (name:'yellow'; r:255; g:255; b:0; a:255 ) , + (name:'yellowgreen'; r:154; g:205; b:50; a:255 ) , + (name:'zzzzzzzzzzz'; r:0; g:0; b:0; a:0 ) ); + + pageEqHigh : shortstring = + #1#2#3#4#5#6#7#8#9#10#11#12#13#14#15#16 + + #17#18#19#20#21#22#23#24#25#26#27#28#29#30#31#32 + + #33#34#35#36#37#38#39#40#41#42#43#44#45#46#47#48 + + #49#50#51#52#53#54#55#56#57#58#59#60#61#62#63#64 + + #65#66#67#68#69#70#71#72#73#74#75#76#77#78#79#80 + + #81#82#83#84#85#86#87#88#89#90#91#92#93#94#95#96 + + #65#66#67#68#69#70#71#72#73#74#75#76#77#78#79#80 + + #81#82#83#84#85#86#87#88#89#90#123#124#125#126#127#128 + + #129#130#131#132#133#134#135#136#137#138#139#140#141#142#143#144 + + #145#146#147#148#149#150#151#152#153#154#155#156#157#158#159#160 + + #161#162#163#164#165#166#167#168#169#170#171#172#173#174#175#176 + + #177#178#179#180#181#182#183#184#185#186#187#188#189#190#191#192 + + #193#194#195#196#197#198#199#200#201#202#203#204#205#206#207#208 + + #209#210#211#212#213#214#215#216#217#218#219#220#221#222#223#224 + + #225#226#227#228#229#230#231#232#233#234#235#236#237#238#239#240 + + #241#242#243#244#245#246#247#248#249#250#251#252#253#254#255; + +{ UNIT IMPLEMENTATION } +{ START_ELEMENT } +procedure start_element; +var + this : parser_ptr; + +begin + this:=parser_ptr(data ); + + if StrComp(PChar(el ) ,'title' ) = 0 then + this.m_title_flag:=true + else + if StrComp(PChar(el ) ,'g' ) = 0 then + begin + this.m_path.push_attr; + this.parse_attr(attr ); + + end + else + if StrComp(PChar(el ) ,'path' ) = 0 then + begin + if this.m_path_flag then + raise svg_exception.Construct(PChar('start_element: Nested path' ) ); + + this.m_path.begin_path; + this.parse_path(attr ); + this.m_path.end_path; + + this.m_path_flag:=true; + + end + else + if StrComp(PChar(el ) ,'rect' ) = 0 then + this.parse_rect(attr ) + else + if StrComp(PChar(el ) ,'line' ) = 0 then + this.parse_line(attr ) + else + if StrComp(PChar(el ) ,'polyline' ) = 0 then + this.parse_poly(attr ,false ) + else + if StrComp(PChar(el ) ,'polygon' ) = 0 then + this.parse_poly(attr ,true ); + + //else + // if StrComp(PChar(el ) ,'<OTHER_ELEMENTS>' ) = 0 then + // begin + // end + //... + +end; + +{ END_ELEMENT } +procedure end_element; +var + this : parser_ptr; + +begin + this:=parser_ptr(data ); + + if StrComp(PChar(el ) ,'title' ) = 0 then + this.m_title_flag:=false + else + if StrComp(PChar(el ) ,'g' ) = 0 then + this.m_path.pop_attr + else + if StrComp(PChar(el ) ,'path' ) = 0 then + this.m_path_flag:=false; + + //else + // if StrComp(PChar(el ) ,'<OTHER_ELEMENTS>' ) = 0 then + // begin + // end + // ... + +end; + +{ CONTENT } +procedure content; +var + this : parser_ptr; + +begin + this:=parser_ptr(data ); + +// m_title_flag signals that the <title> tag is being parsed now. +// The following code concatenates the pieces of content of the <title> tag. + if this.m_title_flag then + begin + if len + this.m_title_len > 255 then + len:=255 - this.m_title_len; + + if len > 0 then + begin + move( + s^ , + char_ptr(ptrcomp(this.m_title ) + this.m_title_len )^ , + len ); + + inc(this.m_title_len ,len ); + + char_ptr(ptrcomp(this.m_title ) + this.m_title_len )^:=#0; + + end; + + end; + +end; + +{ hex_unsigned } +function hex_unsigned(hexstr : agg_basics.char_ptr ) : unsigned; + +function xyint(x ,y : integer ) : integer; +var + f : integer; + m : boolean; + +begin + m:=false; + + if y < 0 then + begin + y:=y * -1; + m:=true; + + end; + + result:=x; + + if y > 1 then + for f:=1 to y - 1 do + result:=result * x; + + if m then + result:=result * -1; + +end; + +var + h : shortstring; + fcb : byte; + yps , + mul , + num : unsigned; + +label + Err ,Esc ; + +const + hex : string[16 ] = '0123456789ABCDEF'; + +begin + h:=''; + + while hexstr^ <> #0 do + begin + h:=h + pageEqHigh[byte(hexstr^ ) ]; + + inc(ptrcomp(hexstr ) ); + + end; + + if length(h ) > 0 then + begin + case h[length(h ) ] of + '0'..'9' ,'A'..'F' : + else + goto Err; + + end; + + num:=pos(h[length(h ) ] ,hex ) - 1; + yps:=2; + mul:=xyint(4 ,yps ); + + if length(h ) > 1 then + for fcb:=length(h ) - 1 downto 1 do + begin + case h[fcb ] of + '0'..'9' ,'A'..'F' : + else + goto Err; + + end; + + inc(num ,(pos(h[fcb ] ,hex ) - 1 ) * mul ); + inc(yps ,2 ); + + mul:=xyint(4 ,yps ); + + end; + + goto Esc; + + end; + +Err: + num:=0; + +Esc: + result:=num; + +end; + +{ parse_color } +function parse_color(str : agg_basics.char_ptr ) : aggclr; +var + u : unsigned; + p : named_color_ptr; + m : shortstring; + +begin + while str^ = ' ' do + inc(ptrcomp(str ) ); + + if str^ = '#' then + begin + inc(ptrcomp(str ) ); + + u:=hex_unsigned(str ); + + result.Construct(rgb8_packed(u ) ); + + end + else + begin + p:=NIL; + + for u:=0 to colors_num - 1 do + if StrComp(colors[u ].name ,PChar(str ) ) = 0 then + begin + p:=@colors[u ]; + + break; + + end; + + if p = NIL then + begin + m:='parse_color: Invalid color name ' + StrPas(PChar(str ) ) + #0; + + raise svg_exception.Construct(PChar(@m[1 ] ) ); + + end; + + result.ConstrInt(p.r ,p.g ,p.b ,p.a ); + + end; + +end; + +{ parse_double } +function parse_double(str : agg_basics.char_ptr ) : double; +begin + while str^ = ' ' do + inc(ptrcomp(str ) ); + + result:=get_double(pointer(PChar(str ) ) ); + +end; + +{ islower } +function islower(ch : char ) : boolean; +begin + case ch of + #97..#122 : + result:=true; + + else + result:=false; + + end; + +end; + +{ is_numeric } +function is_numeric(ch : char ) : boolean; +begin + result:=Pos(ch ,'0123456789+-.eE' ) <> 0; + +end; + +{ parse_transform_args } +function parse_transform_args(str : agg_basics.char_ptr; args : double_ptr; max_na : unsigned; na : unsigned_ptr ) : unsigned; +var + ptr ,end_ : agg_basics.char_ptr; + +begin + na^:=0; + ptr:=str; + + while (ptr^ <> #0 ) and + (ptr^ <> '(' ) do + inc(ptrcomp(ptr ) ); + + if ptr^ = #0 then + raise svg_exception.Construct(PChar('parse_transform_args: Invalid syntax' ) ); + + end_:=ptr; + + while (end_^ <> #0 ) and + (end_^ <> ')' ) do + inc(ptrcomp(end_ ) ); + + if end_^ = #0 then + raise svg_exception.Construct(PChar('parse_transform_args: Invalid syntax' ) ); + + while ptrcomp(ptr ) < ptrcomp(end_ ) do + if is_numeric(ptr^ ) then + begin + if na^ >= max_na then + raise svg_exception.Construct(PChar('parse_transform_args: Too many arguments' ) ); + + double_ptr(ptrcomp(args ) + na^ * sizeof(double ) )^:=get_double(ptr ); + + inc(na^ ); + + while (ptrcomp(ptr ) < ptrcomp(end_ ) ) and + is_numeric(ptr^ ) do + inc(ptrcomp(ptr ) ); + + end + else + inc(ptrcomp(ptr ) ); + + result:=unsigned(ptrcomp(end_ ) - ptrcomp(str ) ); + +end; + +{ CONSTRUCT } +constructor parser.Construct; +begin + m_path:=path; + + m_tokenizer.Construct; + + agg_getmem(pointer(m_buf ) ,buf_size ); + agg_getmem(pointer(m_title ) ,256 ); + + m_title_len :=0; + m_title_flag:=false; + m_path_flag :=false; + + m_attr_name_aloc :=128; + m_attr_value_aloc:=1024; + + agg_getmem(pointer(m_attr_name ) ,m_attr_name_aloc ); + agg_getmem(pointer(m_attr_value ) ,m_attr_value_aloc ); + + m_attr_name_len :=127; + m_attr_value_len:=1023; + + m_title^:=#0; + +end; + +{ DESTRUCT } +destructor parser.Destruct; +begin + agg_freemem(pointer(m_attr_value ) ,m_attr_value_aloc ); + agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc ); + agg_freemem(pointer(m_title ) ,256 ); + agg_freemem(pointer(m_buf ) ,buf_size ); + +end; + +{ PARSE } +procedure parser.parse; +var + msg : array[0..1023 ] of char; + + p : XML_Parser; + af : api_file; + ts : char_ptr; + + done : boolean; + len : int; + +begin + p:=XML_ParserCreate(NIL ); + + if p = NIL then + raise svg_exception.Construct(PChar('Couldn''t allocate memory for parser' ) ); + + XML_SetUserData (p ,@self ); + XML_SetElementHandler (p ,@start_element ,@end_element ); + XML_SetCharacterDataHandler(p ,@content ); + + fname:=fname + #0; + + dec(byte(fname[0 ] ) ); + + if not api_open_file(af ,fname ) then + begin + sprintf(@msg[0 ] ,'Couldn''t open file %s' ,unsigned(@fname[1 ] ) ); + + XML_ParserFree(p ); + + raise svg_exception.Construct(PChar(@msg[0 ] ) ); + + end; + + done:=false; + + repeat + api_read_file(af ,m_buf ,buf_size ,len ); + + done:=len < buf_size; + + if XML_Parse(p ,pointer(m_buf ) ,len ,int(done ) ) = XML_STATUS_ERROR then + begin + api_close_file(af ); + XML_ParserFree(p ); + + sprintf( + @msg[0 ] , + '%s at line ' , + unsigned( + XML_ErrorString( + int(XML_GetErrorCode(p ) ) ) ) ); + + sprintf( + @msg[StrLen(msg ) ] , + '%d'#13 , + XML_GetCurrentLineNumber(p ) ); + + raise svg_exception.Construct(PChar(@msg[0 ] ) ); + + end; + + until done; + + api_close_file(af ); + XML_ParserFree(p ); + + ts:=m_title; + + while ts^ <> #0 do + begin + if byte(ts^ ) < byte(' ' ) then + ts^:=' '; + + inc(ptrcomp(ts ) ); + + end; + +end; + +{ TITLE } +function parser.title; +begin + result:=m_title; + +end; + +{ PARSE_ATTR } +procedure parser.parse_attr(attr : char_ptr_ptr ); +var + i : int; + +begin + i:=0; + + while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do + begin + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'style' ) = 0 then + parse_style(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) + else + parse_attr( + agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ , + agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + inc(i ,2 ); + + end; + +end; + +{ PARSE_PATH } +procedure parser.parse_path; +var + i : int; + + tmp : array[0..3 ] of agg_basics.char_ptr; + +begin + i:=0; + + while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do + begin + // The <path> tag can consist of the path itself ("d=") + // as well as of other parameters like "style=", "transform=", etc. + // In the last case we simply rely on the function of parsing + // attributes (see 'else' branch). + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'d' ) = 0 then + begin + m_tokenizer.set_path_str(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + m_path.parse_path(@m_tokenizer ); + + end + else + begin + // Create a temporary single pair "name-value" in order + // to avoid multiple calls for the same attribute. + tmp[0 ]:=agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^; + tmp[1 ]:=agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^; + tmp[2 ]:=NIL; + tmp[3 ]:=NIL; + + parse_attr(@tmp ); + + end; + + inc(i ,2 ); + + end; + +end; + +{ PARSE_POLY } +procedure parser.parse_poly; +var + i : int; + + x ,y : double; + +begin + x:=0.0; + y:=0.0; + + m_path.begin_path; + + i:=0; + + while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do + begin + if not parse_attr( + agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ , + agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then + if StrComp(PChar(agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'points' ) = 0 then + begin + m_tokenizer.set_path_str(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + if not m_tokenizer.next then + raise svg_exception.Construct(PChar('parse_poly: Too few coordinates' ) ); + + x:=m_tokenizer.last_number; + + if not m_tokenizer.next then + raise svg_exception.Construct(PChar('parse_poly: Too few coordinates' ) ); + + y:=m_tokenizer.last_number; + + m_path.move_to(x ,y ); + + while m_tokenizer.next do + begin + x:=m_tokenizer.last_number; + + if not m_tokenizer.next then + raise svg_exception.Construct(PChar('parse_poly: Odd number of coordinates' ) ); + + y:=m_tokenizer.last_number; + + m_path.line_to(x ,y ); + + end; + + end; + + inc(i ,2 ); + + end; + + m_path.end_path; + +end; + +{ PARSE_RECT } +procedure parser.parse_rect; +var + i : int; + + x ,y ,w ,h : double; + +begin + x:=0.0; + y:=0.0; + w:=0.0; + h:=0.0; + + m_path.begin_path; + + i:=0; + + while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do + begin + if not parse_attr( + agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ , + agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then + begin + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x' ) = 0 then + x:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y' ) = 0 then + y:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'width' ) = 0 then + w:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'height' ) = 0 then + h:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + // rx - to be implemented + // ry - to be implemented + + end; + + inc(i ,2 ); + + end; + + if (w <> 0.0 ) and + (h <> 0.0 ) then + begin + if w < 0.0 then + raise svg_exception.Construct(PChar('parse_rect: Invalid width: ' ) ); + + if h < 0.0 then + raise svg_exception.Construct(PChar('parse_rect: Invalid height: ' ) ); + + m_path.move_to(x ,y ); + m_path.line_to(x + w ,y ); + m_path.line_to(x + w ,y + h ); + m_path.line_to(x ,y + h ); + m_path.close_subpath; + + end; + + m_path.end_path; + +end; + +{ PARSE_LINE } +procedure parser.parse_line; +var + i : int; + + x1 ,y1 ,x2 ,y2 : double; + +begin + x1:=0.0; + y1:=0.0; + x2:=0.0; + y2:=0.0; + + m_path.begin_path; + + i:=0; + + while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do + begin + if not parse_attr( + agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ , + agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then + begin + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x1' ) = 0 then + x1:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y1' ) = 0 then + y1:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x2' ) = 0 then + x2:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y2' ) = 0 then + y2:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ); + + end; + + inc(i ,2 ); + + end; + + m_path.move_to(x1 ,y1 ); + m_path.line_to(x2 ,y2 ); + m_path.end_path; + +end; + +{ PARSE_STYLE } +procedure parser.parse_style; +var + nv_start ,nv_end : agg_basics.char_ptr; + +begin + while str^ <> #0 do + begin + // Left Trim + while (str^ <> #0 ) and + (str^ = ' ' ) do + inc(ptrcomp(str ) ); + + nv_start:=str; + + while (str^ <> #0 ) and + (str^ <> ';' ) do + inc(ptrcomp(str ) ); + + nv_end:=str; + + // Right Trim + while (ptrcomp(nv_end ) > ptrcomp(nv_start ) ) and + ((nv_end^ = ';' ) or + (nv_end^ = ' ' ) ) do + dec(ptrcomp(nv_end ) ); + + inc(ptrcomp(nv_end ) ); + + parse_name_value(nv_start ,nv_end ); + + if str^ <> #0 then + inc(ptrcomp(str ) ); + + end; + +end; + +{ PARSE_TRANSFORM } +procedure parser.parse_transform; +begin + while str^ <> #0 do + begin + if islower(str^ ) then + if StrLComp(PChar(str ) ,'matrix' ,6 ) = 0 then + inc(ptrcomp(str ) ,parse_matrix(str ) ) + else + if StrLComp(PChar(str ) ,'translate' ,9 ) = 0 then + inc(ptrcomp(str ) ,parse_translate(str ) ) + else + if StrLComp(PChar(str ) ,'rotate' ,6 ) = 0 then + inc(ptrcomp(str ) ,parse_rotate(str ) ) + else + if StrLComp(PChar(str ) ,'scale' ,5 ) = 0 then + inc(ptrcomp(str ) ,parse_scale(str ) ) + else + if StrLComp(PChar(str ) ,'skewX' ,5 ) = 0 then + inc(ptrcomp(str ) ,parse_skew_x(str ) ) + else + if StrLComp(PChar(str ) ,'skewY' ,5 ) = 0 then + inc(ptrcomp(str ) ,parse_skew_y(str ) ) + else + inc(ptrcomp(str ) ) + + else + inc(ptrcomp(str ) ); + + end; + +end; + +{ PARSE_MATRIX } +function parser.parse_matrix; +var + args : array[0..5 ] of double; + + na ,len : unsigned; + + ta : trans_affine; + +begin + na :=0; + len:=parse_transform_args(str ,@args ,6 ,@na ); + + if na <> 6 then + raise svg_exception.Construct(PChar('parse_matrix: Invalid number of arguments' ) ); + + ta.Construct(args[0 ] ,args[1 ] ,args[2 ] ,args[3 ] ,args[4 ] ,args[5 ] ); + + m_path.transform.premultiply(@ta ); + + result:=len; + +end; + +{ PARSE_TRANSLATE } +function parser.parse_translate; +var + args : array[0..1 ] of double; + + na ,len : unsigned; + + tat : trans_affine_translation; + +begin + na :=0; + len:=parse_transform_args(str ,@args ,2 ,@na ); + + if na = 1 then + args[1 ]:=0.0; + + tat.Construct(args[0 ] ,args[1 ] ); + + m_path.transform.premultiply(@tat ); + + result:=len; + +end; + +{ PARSE_ROTATE } +function parser.parse_rotate; +var + args : array[0..2 ] of double; + + na ,len : unsigned; + + tar : trans_affine_rotation; + + tat ,t : trans_affine_translation; + +begin + na :=0; + len:=parse_transform_args(str ,@args ,3 ,@na ); + + if na = 1 then + begin + tar.Construct(deg2rad(args[0 ] ) ); + + m_path.transform.premultiply(@tar ); + + end + else + if na = 3 then + begin + t.Construct(-args[1 ] ,-args[2 ] ); + + tar.Construct(deg2rad(args[0 ] ) ); + tat.Construct(args[1 ] ,args[2 ] ); + + t.multiply(@tar ); + t.multiply(@tat ); + + m_path.transform.premultiply(@t ); + + end + else + raise svg_exception.Construct(PChar('parse_rotate: Invalid number of arguments' ) ); + + result:=len; + +end; + +{ PARSE_SCALE } +function parser.parse_scale; +var + args : array[0..1 ] of double; + + na ,len : unsigned; + + tas : trans_affine_scaling; + +begin + na :=0; + len:=parse_transform_args(str ,@args ,2 ,@na ); + + if na = 1 then + args[1 ]:=args[0 ]; + + tas.Construct(args[0 ] ,args[1 ] ); + + m_path.transform.premultiply(@tas ); + + result:=len; + +end; + +{ PARSE_SKEW_X } +function parser.parse_skew_x; +var + arg : double; + + na ,len : unsigned; + + tas : trans_affine_skewing; + +begin + na :=0; + len:=parse_transform_args(str ,@arg ,1 ,@na ); + + tas.Construct(deg2rad(arg ) ,0.0 ); + + m_path.transform.premultiply(@tas ); + + result:=len; + +end; + +{ PARSE_SKEW_Y } +function parser.parse_skew_y; +var + arg : double; + + na ,len : unsigned; + + tas : trans_affine_skewing; + +begin + na :=0; + len:=parse_transform_args(str ,@arg ,1 ,@na ); + + tas.Construct(0.0 ,deg2rad(arg ) ); + + m_path.transform.premultiply(@tas ); + + result:=len; + +end; + +{ PARSE_ATTR } +function parser.parse_attr(name ,value : agg_basics.char_ptr ) : boolean; +var + clr : aggclr; + +begin + result:=true; + + if StrComp(PChar(name ) ,'style' ) = 0 then + parse_style(value ) + else + if StrComp(PChar(name ) ,'fill' ) = 0 then + if StrComp(PChar(value ) ,'none' ) = 0 then + m_path.fill_none + else + begin + clr:=parse_color(value ); + + m_path.fill(@clr ); + + end + else + if StrComp(PChar(name ) ,'fill-opacity' ) = 0 then + m_path.fill_opacity(parse_double(value ) ) + else + if StrComp(PChar(name ) ,'stroke' ) = 0 then + if StrComp(PChar(value ) ,'none' ) = 0 then + m_path.stroke_none + else + begin + clr:=parse_color(value ); + + m_path.stroke(@clr ); + + end + else + if StrComp(PChar(name ) ,'stroke-width' ) = 0 then + m_path.stroke_width(parse_double(value ) ) + else + if StrComp(PChar(name ) ,'stroke-linecap' ) = 0 then + begin + if StrComp(PChar(value ) ,'butt' ) = 0 then + m_path.line_cap(butt_cap ) + else + if StrComp(PChar(value ) ,'round' ) = 0 then + m_path.line_cap(round_cap ) + else + if StrComp(PChar(value ) ,'square' ) = 0 then + m_path.line_cap(square_cap ); + + end + else + if StrComp(PChar(name ) ,'stroke-linejoin' ) = 0 then + begin + if StrComp(PChar(value ) ,'miter' ) = 0 then + m_path.line_join(miter_join ) + else + if StrComp(PChar(value ) ,'round' ) = 0 then + m_path.line_join(round_join ) + else + if StrComp(PChar(value ) ,'bevel' ) = 0 then + m_path.line_join(bevel_join ); + + end + else + if StrComp(PChar(name ) ,'stroke-miterlimit' ) = 0 then + m_path.miter_limit(parse_double(value ) ) + else + if StrComp(PChar(name ) ,'stroke-opacity' ) = 0 then + m_path.stroke_opacity(parse_double(value ) ) + else + if StrComp(PChar(name ) ,'transform' ) = 0 then + parse_transform(value ) + + //else + // if StrComp(PChar(el ) ,'<OTHER_ATTRIBUTES>' ) = 0 then + // begin + // end + // ... + + else + result:=false; + +end; + +{ PARSE_NAME_VALUE } +function parser.parse_name_value; +var + str ,val : agg_basics.char_ptr; + +begin + str:=nv_start; + + while (ptrcomp(str ) < ptrcomp(nv_end ) ) and + (str^ <> ':' ) do + inc(ptrcomp(str ) ); + + val:=str; + +// Right Trim + while (ptrcomp(str ) > ptrcomp(nv_start ) ) and + ((str^ = ':' ) or + (str^ = ' ' ) ) do + dec(ptrcomp(str ) ); + + inc(ptrcomp(str ) ); + + copy_name(nv_start ,str ); + + while (ptrcomp(val ) < ptrcomp(nv_end ) ) and + ((val^ = ':' ) or + (val^ = ' ' ) ) do + inc(ptrcomp(val ) ); + + copy_value(val ,nv_end ); + + result:=parse_attr(agg_basics.char_ptr(m_attr_name ) ,agg_basics.char_ptr(m_attr_value ) ); + +end; + +{ COPY_NAME } +procedure parser.copy_name; +var + len : unsigned; + +begin + len:=ptrcomp(end_ ) - ptrcomp(start ); + + if (m_attr_name_len = 0 ) or + (len > m_attr_name_len ) then + begin + agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc ); + + m_attr_name_aloc:=len + 1; + + agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc ); + + m_attr_name_len:=len; + + end; + + if len <> 0 then + move(start^ ,m_attr_name^ ,len ); + + char_ptr(ptrcomp(m_attr_name ) + len )^:=#0; + +end; + +{ COPY_VALUE } +procedure parser.copy_value; +var + len : unsigned; + +begin + len:=ptrcomp(end_ ) - ptrcomp(start ); + + if (m_attr_value_len = 0 ) or + (len > m_attr_value_len ) then + begin + agg_freemem(pointer(m_attr_value ) ,m_attr_value_aloc ); + + m_attr_value_aloc:=len + 1; + + agg_getmem(pointer(m_attr_value ) ,m_attr_value_aloc ); + + m_attr_value_len:=len; + + end; + + if len <> 0 then + move(start^ ,m_attr_value^ ,len ); + + char_ptr(ptrcomp(m_attr_value ) + len )^:=#0; + +end; + +END. + diff --git a/src/corelib/render/software/svg/agg_svg_path_renderer.pas b/src/corelib/render/software/svg/agg_svg_path_renderer.pas index c1fa0614..76735424 100644 --- a/src/corelib/render/software/svg/agg_svg_path_renderer.pas +++ b/src/corelib/render/software/svg/agg_svg_path_renderer.pas @@ -1,893 +1,893 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 24.04.2006-Milano: Unit port establishment
-//
-{ agg_svg_path_renderer.pas }
-unit
- agg_svg_path_renderer ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- agg_basics ,
- agg_path_storage ,
- agg_conv_transform ,
- agg_conv_stroke ,
- agg_conv_contour ,
- agg_conv_curve ,
- agg_color ,
- agg_array ,
- agg_bounding_rect ,
- agg_rasterizer_scanline_aa ,
- agg_vertex_source ,
- agg_svg_path_tokenizer ,
- agg_svg_exception ,
- agg_trans_affine ,
- agg_math_stroke ,
- agg_scanline ,
- agg_renderer_scanline ,
- agg_render_scanlines ;
-
-{ TYPES DEFINITION }
-type
- conv_count = object(vertex_source )
- m_source : vertex_source_ptr;
- m_count : unsigned;
-
- constructor Construct(vs : vertex_source_ptr );
-
- procedure count_(n : unsigned );
- function _count : unsigned;
-
- procedure rewind(path_id : unsigned ); virtual;
- function vertex(x ,y : double_ptr ) : unsigned; virtual;
-
- end;
-
-// Basic path attributes
- path_attributes_ptr = ^path_attributes;
- path_attributes = object
- index : unsigned;
-
- fill_color ,
- stroke_color : aggclr;
- fill_flag ,
- stroke_flag ,
- even_odd_flag : boolean;
-
- line_join ,
- line_cap : unsigned;
- miter_limit ,
- stroke_width : double;
-
- transform : trans_affine;
-
- // Empty constructor
- constructor Construct; overload;
-
- // Copy constructor
- constructor Construct(attr : path_attributes_ptr ); overload;
-
- // Copy constructor with new index value
- constructor Construct(attr : path_attributes_ptr; idx : unsigned ); overload;
-
- end;
-
-// Path container and renderer.
- path_renderer_ptr = ^path_renderer;
- path_renderer = object(unsigned_list )
- m_storage : path_storage;
- m_attr_storage ,
- m_attr_stack : pod_deque;
- m_transform : trans_affine;
-
- m_curved : conv_curve;
- m_curved_count : conv_count;
-
- m_curved_stroked : conv_stroke;
- m_curved_stroked_trans : conv_transform;
-
- m_curved_trans : conv_transform;
- m_curved_trans_contour : conv_contour;
-
- constructor Construct;
- destructor Destruct;
-
- procedure remove_all;
-
- // Use these functions as follows:
- // begin_path when the XML tag <path> comes ("start_element" handler)
- // parse_path on "d=" tag attribute
- // end_path when parsing of the entire tag is done.
- procedure begin_path;
- procedure parse_path(tok : path_tokenizer_ptr );
- procedure end_path;
-
- // The following functions are essentially a "reflection" of
- // the respective SVG path commands.
- procedure move_to (x ,y : double; rel : boolean = false ); // M, m
- procedure line_to (x ,y : double; rel : boolean = false ); // L, l
- procedure hline_to(x : double; rel : boolean = false ); // H, h
- procedure vline_to(y : double; rel : boolean = false ); // V, v
-
- procedure curve3(x1 ,y1 ,x ,y : double; rel : boolean = false ); overload; // Q, q
- procedure curve3(x ,y : double; rel : boolean = false ); overload; // T, t
- procedure curve4(x1 ,y1 ,x2 ,y2 ,x ,y : double; rel : boolean = false ); overload; // C, c
- procedure curve4(x2 ,y2 ,x ,y : double; rel : boolean = false ); overload; // S, s
-
- procedure close_subpath; // Z, z
-
- procedure add_path(vs : vertex_source_ptr; path_id : unsigned = 0; solid_path : boolean = true );
- function vertex_count : unsigned;
-
- // Call these functions on <g> tag (start_element, end_element respectively)
- procedure push_attr;
- procedure pop_attr;
-
- // Attribute setting functions
- procedure fill (f : aggclr_ptr );
- procedure stroke (s : aggclr_ptr );
- procedure even_odd (flag : boolean );
- procedure stroke_width(w : double );
-
- procedure fill_none;
- procedure stroke_none;
-
- procedure fill_opacity (op : double );
- procedure stroke_opacity(op : double );
- procedure line_join (join : unsigned );
- procedure line_cap (cap : unsigned );
- procedure miter_limit (ml : double );
-
- function transform : trans_affine_ptr;
-
- // Make all polygons CCW-oriented
- procedure arrange_orientations;
-
- // Expand all polygons
- procedure expand(value : double );
-
- function array_operator(idx : unsigned ) : unsigned; virtual;
- procedure bounding_rect (x1 ,y1 ,x2 ,y2 : double_ptr );
-
- // Rendering. One can specify two additional parameters:
- // trans_affine and opacity. They can be used to transform the whole
- // image and/or to make it translucent.
- procedure render(
- ras : rasterizer_scanline_ptr;
- sl : scanline_ptr;
- ren : renderer_scanline_ptr;
- mtx : trans_affine_ptr;
- cb : rect_ptr;
- opacity : double = 1.0 );
-
- // Private
- function cur_attr : path_attributes_ptr;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor conv_count.Construct;
-begin
- m_source:=vs;
- m_count :=0;
-
-end;
-
-{ COUNT_ }
-procedure conv_count.count_;
-begin
- m_count:=n;
-
-end;
-
-{ _COUNT }
-function conv_count._count;
-begin
- result:=m_count;
-
-end;
-
-{ REWIND }
-procedure conv_count.rewind;
-begin
- m_source.rewind(path_id );
-
-end;
-
-{ VERTEX }
-function conv_count.vertex;
-begin
- inc(m_count );
-
- result:=m_source.vertex(x ,y );
-
-end;
-
-{ CONSTRUCT }
-constructor path_attributes.Construct;
-begin
- index:=0;
-
- fill_color.ConstrInt (0 ,0 ,0 );
- stroke_color.ConstrInt(0 ,0 ,0 );
-
- fill_flag :=true;
- stroke_flag :=false;
- even_odd_flag:=false;
- line_join :=miter_join;
- line_cap :=butt_cap;
- miter_limit :=4.0;
- stroke_width :=1.0;
-
- transform.Construct;
-
-end;
-
-{ CONSTRUCT }
-constructor path_attributes.Construct(attr : path_attributes_ptr );
-begin
- index:=attr.index;
-
- fill_color.Construct (@attr.fill_color );
- stroke_color.Construct(@attr.stroke_color );
-
- fill_flag :=attr.fill_flag;
- stroke_flag :=attr.stroke_flag;
- even_odd_flag:=attr.even_odd_flag;
- line_join :=attr.line_join;
- line_cap :=attr.line_cap;
- miter_limit :=attr.miter_limit;
- stroke_width :=attr.stroke_width;
-
- transform.Construct;
- transform.assign_all(@attr.transform );
-
-end;
-
-{ CONSTRUCT }
-constructor path_attributes.Construct(attr : path_attributes_ptr; idx : unsigned );
-begin
- index:=idx;
-
- fill_color.Construct (@attr.fill_color );
- stroke_color.Construct(@attr.stroke_color );
-
- fill_flag :=attr.fill_flag;
- stroke_flag :=attr.stroke_flag;
- even_odd_flag:=attr.even_odd_flag;
- line_join :=attr.line_join;
- line_cap :=attr.line_cap;
- miter_limit :=attr.miter_limit;
- stroke_width :=attr.stroke_width;
-
- transform.Construct;
- transform.assign_all(@attr.transform );
-
-end;
-
-{ CONSTRUCT }
-constructor path_renderer.Construct;
-begin
- m_storage.Construct;
- m_attr_storage.Construct(sizeof(path_attributes ) );
- m_attr_stack.Construct(sizeof(path_attributes ) );
- m_transform.Construct;
-
- m_curved.Construct (@m_storage );
- m_curved_count.Construct(@m_curved );
-
- m_curved_stroked.Construct (@m_curved_count );
- m_curved_stroked_trans.Construct(@m_curved_stroked ,@m_transform );
-
- m_curved_trans.Construct (@m_curved_count ,@m_transform );
- m_curved_trans_contour.Construct(@m_curved_trans );
-
-end;
-
-{ DESTRUCT }
-destructor path_renderer.Destruct;
-begin
- m_curved_trans_contour.Destruct;
- m_curved_stroked.Destruct;
- m_curved.Destruct;
-
- m_attr_stack.Destruct;
- m_attr_storage.Destruct;
- m_storage.Destruct;
-
-end;
-
-{ REMOVE_ALL }
-procedure path_renderer.remove_all;
-begin
- m_storage.remove_all;
- m_attr_storage.remove_all;
- m_attr_stack.remove_all;
- m_transform.reset;
-
-end;
-
-{ BEGIN_PATH }
-procedure path_renderer.begin_path;
-var
- idx : unsigned;
- attr : path_attributes;
-
-begin
- push_attr;
-
- idx:=m_storage.start_new_path;
-
- attr.Construct(cur_attr ,idx );
-
- m_attr_storage.add(@attr );
-
-end;
-
-{ PARSE_PATH }
-procedure path_renderer.parse_path;
-var
- arg : array[0..9 ] of double;
- i : unsigned;
- cmd : char;
- buf : array[0..99 ] of char;
-
-begin
- while tok.next do
- begin
- cmd:=tok.last_command;
-
- case cmd of
- 'M' ,'m' :
- begin
- arg[0 ]:=tok.last_number;
- arg[1 ]:=tok.next(cmd );
-
- move_to(arg[0 ] ,arg[1 ] ,cmd = 'm' );
-
- end;
-
- 'L' ,'l' :
- begin
- arg[0 ]:=tok.last_number;
- arg[1 ]:=tok.next(cmd );
-
- line_to(arg[0 ] ,arg[1 ] ,cmd = 'l' );
-
- end;
-
- 'V' ,'v' :
- vline_to(tok.last_number ,cmd = 'v' );
-
- 'H' ,'h' :
- hline_to(tok.last_number ,cmd = 'h' );
-
- 'Q' ,'q' :
- begin
- arg[0 ]:=tok.last_number;
-
- for i:=1 to 3 do
- arg[i ]:=tok.next(cmd );
-
- curve3(arg[0 ] ,arg[1 ] ,arg[2 ] ,arg[3 ] ,cmd = 'q' );
-
- end;
-
- 'T' ,'t' :
- begin
- arg[0 ]:=tok.last_number;
- arg[1 ]:=tok.next(cmd );
-
- curve3(arg[0 ] ,arg[1 ] ,cmd = 't' );
-
- end;
-
- 'C' ,'c' :
- begin
- arg[0 ]:=tok.last_number;
-
- for i:=1 to 5 do
- arg[i ]:=tok.next(cmd );
-
- curve4(arg[0 ] ,arg[1 ] ,arg[2 ] ,arg[3 ] ,arg[4 ] ,arg[5 ] ,cmd = 'c' );
-
- end;
-
- 'S' ,'s' :
- begin
- arg[0 ]:=tok.last_number;
-
- for i:=1 to 3 do
- arg[i ]:=tok.next(cmd );
-
- curve4(arg[0 ] ,arg[1 ] ,arg[2 ] ,arg[3 ] ,cmd = 's' );
-
- end;
-
- 'A' ,'a' :
- raise svg_exception.Construct(PChar('parse_path: Command A: NOT IMPLEMENTED YET' ) );
-
- 'Z' ,'z' :
- close_subpath;
-
- else
- begin
- sprintf(@buf[0 ] ,'parse_path: Invalid Command %c' ,unsigned(cmd ) );
-
- raise svg_exception.Construct(PChar(@buf[0 ] ) );
-
- end;
-
- end;
-
- end;
-
-end;
-
-{ END_PATH }
-procedure path_renderer.end_path;
-var
- idx : unsigned;
- attr : path_attributes;
-
-begin
- if m_attr_storage.size = 0 then
- raise svg_exception(PChar('end_path : The path was not begun' ) );
-
- attr.Construct(cur_attr );
-
- idx :=path_attributes_ptr(m_attr_storage.array_operator(m_attr_storage.size - 1 ) ).index;
- attr.index:=idx;
-
- move(
- pointer(@attr )^ ,
- path_attributes_ptr(m_attr_storage.array_operator(m_attr_storage.size - 1 ) )^ ,
- sizeof(path_attributes ) );
-
- pop_attr;
-
-end;
-
-{ MOVE_TO }
-procedure path_renderer.move_to;
-begin
- if rel then
- m_storage.rel_to_abs(@x ,@y );
-
- m_storage.move_to(x ,y );
-
-end;
-
-{ LINE_TO }
-procedure path_renderer.line_to;
-begin
- if rel then
- m_storage.rel_to_abs(@x ,@y );
-
- m_storage.line_to(x ,y );
-
-end;
-
-{ HLINE_TO }
-procedure path_renderer.hline_to;
-var
- x2 ,y2 : double;
-
-begin
- x2:=0.0;
- y2:=0.0;
-
- if m_storage.total_vertices <> 0 then
- begin
- m_storage.vertex_(m_storage.total_vertices - 1 ,@x2 ,@y2 );
-
- if rel then
- x:=x + x2;
-
- m_storage.line_to(x ,y2 );
-
- end;
-
-end;
-
-{ VLINE_TO }
-procedure path_renderer.vline_to;
-var
- x2 ,y2 : double;
-
-begin
- x2:=0.0;
- y2:=0.0;
-
- if m_storage.total_vertices <> 0 then
- begin
- m_storage.vertex_(m_storage.total_vertices - 1 ,@x2 ,@y2 );
-
- if rel then
- y:=y + y2;
-
- m_storage.line_to(x2 ,y );
-
- end;
-
-end;
-
-{ CURVE3 }
-procedure path_renderer.curve3(x1 ,y1 ,x ,y : double; rel : boolean = false );
-begin
- if rel then
- begin
- m_storage.rel_to_abs(@x1 ,@y1 );
- m_storage.rel_to_abs(@x ,@y );
-
- end;
-
- m_storage.curve3(x1 ,y1 ,x ,y );
-
-end;
-
-{ CURVE3 }
-procedure path_renderer.curve3(x ,y : double; rel : boolean = false );
-begin
-// raise exception("curve3(x, y) : NOT IMPLEMENTED YET");
- if rel then
- m_storage.curve3_rel(x ,y )
- else
- m_storage.curve3(x ,y );
-
-end;
-
-{ CURVE4 }
-procedure path_renderer.curve4(x1 ,y1 ,x2 ,y2 ,x ,y : double; rel : boolean = false );
-begin
- if rel then
- begin
- m_storage.rel_to_abs(@x1 ,@y1 );
- m_storage.rel_to_abs(@x2 ,@y2 );
- m_storage.rel_to_abs(@x ,@y );
-
- end;
-
- m_storage.curve4(x1 ,y1 ,x2 ,y2 ,x ,y );
-
-end;
-
-{ CURVE4 }
-procedure path_renderer.curve4(x2 ,y2 ,x ,y : double; rel : boolean = false );
-begin
-//throw exception("curve4(x2, y2, x, y) : NOT IMPLEMENTED YET");
- if rel then
- m_storage.curve4_rel(x2 ,y2 ,x ,y )
- else
- m_storage.curve4(x2 ,y2 ,x ,y );
-
-end;
-
-{ CLOSE_SUBPATH }
-procedure path_renderer.close_subpath;
-begin
- m_storage.end_poly(path_flags_close );
-
-end;
-
-{ ADD_PATH }
-procedure path_renderer.add_path;
-begin
- m_storage.add_path(vs ,path_id ,solid_path );
-
-end;
-
-{ VERTEX_COUNT }
-function path_renderer.vertex_count;
-begin
- result:=m_curved_count._count;
-
-end;
-
-{ PUSH_ATTR }
-procedure path_renderer.push_attr;
-var
- attr : path_attributes;
-
-begin
- if m_attr_stack.size <> 0 then
- m_attr_stack.add(
- m_attr_stack.array_operator(m_attr_stack.size - 1 ) )
- else
- begin
- attr.Construct;
-
- m_attr_stack.add(@attr );
-
- end;
-
-end;
-
-{ POP_ATTR }
-procedure path_renderer.pop_attr;
-begin
- if m_attr_stack.size = 0 then
- raise svg_exception(PChar('pop_attr : Attribute stack is empty' ) );
-
- m_attr_stack.remove_last;
-
-end;
-
-{ FILL }
-procedure path_renderer.fill;
-var
- attr : path_attributes_ptr;
-
-begin
- attr:=cur_attr;
-
- attr.fill_color:=f^;
- attr.fill_flag :=true;
-
-end;
-
-{ STROKE }
-procedure path_renderer.stroke;
-var
- attr : path_attributes_ptr;
-
-begin
- attr:=cur_attr;
-
- attr.stroke_color:=s^;
- attr.stroke_flag :=true;
-
-end;
-
-{ EVEN_ODD }
-procedure path_renderer.even_odd;
-begin
- cur_attr.even_odd_flag:=flag;
-
-end;
-
-{ STROKE_WIDTH }
-procedure path_renderer.stroke_width;
-var
- attr : path_attributes_ptr;
-
-begin
- attr:=cur_attr;
-
- attr.stroke_width:=w;
- attr.stroke_flag :=true;
-
-end;
-
-{ FILL_NONE }
-procedure path_renderer.fill_none;
-begin
- cur_attr.fill_flag:=false;
-
-end;
-
-{ STROKE_NONE }
-procedure path_renderer.stroke_none;
-begin
- cur_attr.stroke_flag:=false;
-
-end;
-
-{ FILL_OPACITY }
-procedure path_renderer.fill_opacity;
-begin
- cur_attr.fill_color.opacity_(op );
-
-end;
-
-{ STROKE_OPACITY }
-procedure path_renderer.stroke_opacity;
-begin
- cur_attr.stroke_color.opacity_(op );
-
-end;
-
-{ LINE_JOIN }
-procedure path_renderer.line_join;
-begin
- cur_attr.line_join:=join;
-
-end;
-
-{ LINE_CAP }
-procedure path_renderer.line_cap;
-begin
- cur_attr.line_cap:=cap;
-
-end;
-
-{ MITER_LIMIT }
-procedure path_renderer.miter_limit;
-begin
- cur_attr.miter_limit:=ml;
-
-end;
-
-{ TRANSFORM }
-function path_renderer.transform;
-begin
- result:=@cur_attr.transform;
-
-end;
-
-{ ARRANGE_ORIENTATIONS }
-procedure path_renderer.arrange_orientations;
-begin
- m_storage.arrange_orientations_all_paths(path_flags_ccw );
-
-end;
-
-{ EXPAND }
-procedure path_renderer.expand;
-begin
- m_curved_trans_contour.width_(value );
-
-end;
-
-{ ARRAY_OPERATOR }
-function path_renderer.array_operator;
-begin
- m_transform.assign_all(
- @path_attributes_ptr(
- m_attr_storage.array_operator(idx ) ).transform );
-
- result:=path_attributes_ptr(m_attr_storage.array_operator(idx ) ).index;
-
-end;
-
-{ BOUNDING_RECT }
-procedure path_renderer.bounding_rect;
-var
- trans : conv_transform;
-
-begin
- trans.Construct(@m_storage ,@m_transform );
-
- bounding_rect_ul(
- @trans ,@self ,0 ,m_attr_storage.size ,x1 ,y1 ,x2 ,y2 );
-
-end;
-
-{ RENDER }
-procedure path_renderer.render;
-var
- i : unsigned;
-
- scl : double;
-
- attr : path_attributes_ptr;
-
- color : aggclr;
-
-begin
- ras.clip_box (cb.x1 ,cb.y1 ,cb.x2 ,cb.y2 );
- m_curved_count.count_(0 );
-
- i:=0;
-
- while i < m_attr_storage.size do
- begin
- attr:=path_attributes_ptr(m_attr_storage.array_operator(i ) );
-
- m_transform.assign_all(@attr.transform );
- m_transform.multiply (mtx );
-
- scl:=m_transform.scale;
-
- //m_curved.approximation_method(curve_inc );
-
- m_curved.approximation_scale_(scl );
- m_curved.angle_tolerance_ (0.0 );
-
- color.Construct;
-
- if attr.fill_flag then
- begin
- ras.reset;
-
- if attr.even_odd_flag then
- ras.filling_rule(fill_even_odd )
- else
- ras.filling_rule(fill_non_zero );
-
- if Abs(m_curved_trans_contour._width ) < 0.0001 then
- ras.add_path(@m_curved_trans ,attr.index )
- else
- begin
- m_curved_trans_contour.miter_limit_(attr.miter_limit );
-
- ras.add_path(@m_curved_trans_contour ,attr.index );
-
- end;
-
- color:=attr.fill_color;
-
- color.opacity_ (color._opacity * opacity );
- ren.color_ (@color );
- render_scanlines(ras ,sl ,ren );
-
- end;
-
- if attr.stroke_flag then
- begin
- m_curved_stroked.width_(attr.stroke_width );
-
- //m_curved_stroked.line_join_((attr.line_join == miter_join) ? miter_join_round : attr.line_join);
-
- m_curved_stroked.line_join_ (attr.line_join );
- m_curved_stroked.line_cap_ (attr.line_cap );
- m_curved_stroked.miter_limit_ (attr.miter_limit );
- m_curved_stroked.approximation_scale_(scl );
-
- // If the *visual* line width is considerable we
- // turn on processing of curve cusps.
- //---------------------
- if attr.stroke_width * scl > 1.0 then
- m_curved.angle_tolerance_(0.2 );
-
- ras.reset;
- ras.filling_rule(fill_non_zero );
- ras.add_path (@m_curved_stroked_trans ,attr.index );
-
- color:=attr.stroke_color;
-
- color.opacity_ (color._opacity * opacity);
- ren.color_ (@color );
- render_scanlines(ras ,sl ,ren );
-
- end;
-
- inc(i );
-
- end;
-
-end;
-
-{ CUR_ATTR }
-function path_renderer.cur_attr;
-begin
- if m_attr_stack.size = 0 then
- raise svg_exception.Construct(PChar('cur_attr : Attribute stack is empty' ) );
-
- result:=
- path_attributes_ptr(
- m_attr_stack.array_operator(m_attr_stack.size - 1 ) );
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 24.04.2006-Milano: Unit port establishment +// +{ agg_svg_path_renderer.pas } +unit + agg_svg_path_renderer ; + +INTERFACE + +{$I agg_mode.inc } + +uses + agg_basics , + agg_path_storage , + agg_conv_transform , + agg_conv_stroke , + agg_conv_contour , + agg_conv_curve , + agg_color , + agg_array , + agg_bounding_rect , + agg_rasterizer_scanline_aa , + agg_vertex_source , + agg_svg_path_tokenizer , + agg_svg_exception , + agg_trans_affine , + agg_math_stroke , + agg_scanline , + agg_renderer_scanline , + agg_render_scanlines ; + +{ TYPES DEFINITION } +type + conv_count = object(vertex_source ) + m_source : vertex_source_ptr; + m_count : unsigned; + + constructor Construct(vs : vertex_source_ptr ); + + procedure count_(n : unsigned ); + function _count : unsigned; + + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + end; + +// Basic path attributes + path_attributes_ptr = ^path_attributes; + path_attributes = object + index : unsigned; + + fill_color , + stroke_color : aggclr; + fill_flag , + stroke_flag , + even_odd_flag : boolean; + + line_join , + line_cap : unsigned; + miter_limit , + stroke_width : double; + + transform : trans_affine; + + // Empty constructor + constructor Construct; overload; + + // Copy constructor + constructor Construct(attr : path_attributes_ptr ); overload; + + // Copy constructor with new index value + constructor Construct(attr : path_attributes_ptr; idx : unsigned ); overload; + + end; + +// Path container and renderer. + path_renderer_ptr = ^path_renderer; + path_renderer = object(unsigned_list ) + m_storage : path_storage; + m_attr_storage , + m_attr_stack : pod_deque; + m_transform : trans_affine; + + m_curved : conv_curve; + m_curved_count : conv_count; + + m_curved_stroked : conv_stroke; + m_curved_stroked_trans : conv_transform; + + m_curved_trans : conv_transform; + m_curved_trans_contour : conv_contour; + + constructor Construct; + destructor Destruct; + + procedure remove_all; + + // Use these functions as follows: + // begin_path when the XML tag <path> comes ("start_element" handler) + // parse_path on "d=" tag attribute + // end_path when parsing of the entire tag is done. + procedure begin_path; + procedure parse_path(tok : path_tokenizer_ptr ); + procedure end_path; + + // The following functions are essentially a "reflection" of + // the respective SVG path commands. + procedure move_to (x ,y : double; rel : boolean = false ); // M, m + procedure line_to (x ,y : double; rel : boolean = false ); // L, l + procedure hline_to(x : double; rel : boolean = false ); // H, h + procedure vline_to(y : double; rel : boolean = false ); // V, v + + procedure curve3(x1 ,y1 ,x ,y : double; rel : boolean = false ); overload; // Q, q + procedure curve3(x ,y : double; rel : boolean = false ); overload; // T, t + procedure curve4(x1 ,y1 ,x2 ,y2 ,x ,y : double; rel : boolean = false ); overload; // C, c + procedure curve4(x2 ,y2 ,x ,y : double; rel : boolean = false ); overload; // S, s + + procedure close_subpath; // Z, z + + procedure add_path(vs : vertex_source_ptr; path_id : unsigned = 0; solid_path : boolean = true ); + function vertex_count : unsigned; + + // Call these functions on <g> tag (start_element, end_element respectively) + procedure push_attr; + procedure pop_attr; + + // Attribute setting functions + procedure fill (f : aggclr_ptr ); + procedure stroke (s : aggclr_ptr ); + procedure even_odd (flag : boolean ); + procedure stroke_width(w : double ); + + procedure fill_none; + procedure stroke_none; + + procedure fill_opacity (op : double ); + procedure stroke_opacity(op : double ); + procedure line_join (join : unsigned ); + procedure line_cap (cap : unsigned ); + procedure miter_limit (ml : double ); + + function transform : trans_affine_ptr; + + // Make all polygons CCW-oriented + procedure arrange_orientations; + + // Expand all polygons + procedure expand(value : double ); + + function array_operator(idx : unsigned ) : unsigned; virtual; + procedure bounding_rect (x1 ,y1 ,x2 ,y2 : double_ptr ); + + // Rendering. One can specify two additional parameters: + // trans_affine and opacity. They can be used to transform the whole + // image and/or to make it translucent. + procedure render( + ras : rasterizer_scanline_ptr; + sl : scanline_ptr; + ren : renderer_scanline_ptr; + mtx : trans_affine_ptr; + cb : rect_ptr; + opacity : double = 1.0 ); + + // Private + function cur_attr : path_attributes_ptr; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor conv_count.Construct; +begin + m_source:=vs; + m_count :=0; + +end; + +{ COUNT_ } +procedure conv_count.count_; +begin + m_count:=n; + +end; + +{ _COUNT } +function conv_count._count; +begin + result:=m_count; + +end; + +{ REWIND } +procedure conv_count.rewind; +begin + m_source.rewind(path_id ); + +end; + +{ VERTEX } +function conv_count.vertex; +begin + inc(m_count ); + + result:=m_source.vertex(x ,y ); + +end; + +{ CONSTRUCT } +constructor path_attributes.Construct; +begin + index:=0; + + fill_color.ConstrInt (0 ,0 ,0 ); + stroke_color.ConstrInt(0 ,0 ,0 ); + + fill_flag :=true; + stroke_flag :=false; + even_odd_flag:=false; + line_join :=miter_join; + line_cap :=butt_cap; + miter_limit :=4.0; + stroke_width :=1.0; + + transform.Construct; + +end; + +{ CONSTRUCT } +constructor path_attributes.Construct(attr : path_attributes_ptr ); +begin + index:=attr.index; + + fill_color.Construct (@attr.fill_color ); + stroke_color.Construct(@attr.stroke_color ); + + fill_flag :=attr.fill_flag; + stroke_flag :=attr.stroke_flag; + even_odd_flag:=attr.even_odd_flag; + line_join :=attr.line_join; + line_cap :=attr.line_cap; + miter_limit :=attr.miter_limit; + stroke_width :=attr.stroke_width; + + transform.Construct; + transform.assign_all(@attr.transform ); + +end; + +{ CONSTRUCT } +constructor path_attributes.Construct(attr : path_attributes_ptr; idx : unsigned ); +begin + index:=idx; + + fill_color.Construct (@attr.fill_color ); + stroke_color.Construct(@attr.stroke_color ); + + fill_flag :=attr.fill_flag; + stroke_flag :=attr.stroke_flag; + even_odd_flag:=attr.even_odd_flag; + line_join :=attr.line_join; + line_cap :=attr.line_cap; + miter_limit :=attr.miter_limit; + stroke_width :=attr.stroke_width; + + transform.Construct; + transform.assign_all(@attr.transform ); + +end; + +{ CONSTRUCT } +constructor path_renderer.Construct; +begin + m_storage.Construct; + m_attr_storage.Construct(sizeof(path_attributes ) ); + m_attr_stack.Construct(sizeof(path_attributes ) ); + m_transform.Construct; + + m_curved.Construct (@m_storage ); + m_curved_count.Construct(@m_curved ); + + m_curved_stroked.Construct (@m_curved_count ); + m_curved_stroked_trans.Construct(@m_curved_stroked ,@m_transform ); + + m_curved_trans.Construct (@m_curved_count ,@m_transform ); + m_curved_trans_contour.Construct(@m_curved_trans ); + +end; + +{ DESTRUCT } +destructor path_renderer.Destruct; +begin + m_curved_trans_contour.Destruct; + m_curved_stroked.Destruct; + m_curved.Destruct; + + m_attr_stack.Destruct; + m_attr_storage.Destruct; + m_storage.Destruct; + +end; + +{ REMOVE_ALL } +procedure path_renderer.remove_all; +begin + m_storage.remove_all; + m_attr_storage.remove_all; + m_attr_stack.remove_all; + m_transform.reset; + +end; + +{ BEGIN_PATH } +procedure path_renderer.begin_path; +var + idx : unsigned; + attr : path_attributes; + +begin + push_attr; + + idx:=m_storage.start_new_path; + + attr.Construct(cur_attr ,idx ); + + m_attr_storage.add(@attr ); + +end; + +{ PARSE_PATH } +procedure path_renderer.parse_path; +var + arg : array[0..9 ] of double; + i : unsigned; + cmd : char; + buf : array[0..99 ] of char; + +begin + while tok.next do + begin + cmd:=tok.last_command; + + case cmd of + 'M' ,'m' : + begin + arg[0 ]:=tok.last_number; + arg[1 ]:=tok.next(cmd ); + + move_to(arg[0 ] ,arg[1 ] ,cmd = 'm' ); + + end; + + 'L' ,'l' : + begin + arg[0 ]:=tok.last_number; + arg[1 ]:=tok.next(cmd ); + + line_to(arg[0 ] ,arg[1 ] ,cmd = 'l' ); + + end; + + 'V' ,'v' : + vline_to(tok.last_number ,cmd = 'v' ); + + 'H' ,'h' : + hline_to(tok.last_number ,cmd = 'h' ); + + 'Q' ,'q' : + begin + arg[0 ]:=tok.last_number; + + for i:=1 to 3 do + arg[i ]:=tok.next(cmd ); + + curve3(arg[0 ] ,arg[1 ] ,arg[2 ] ,arg[3 ] ,cmd = 'q' ); + + end; + + 'T' ,'t' : + begin + arg[0 ]:=tok.last_number; + arg[1 ]:=tok.next(cmd ); + + curve3(arg[0 ] ,arg[1 ] ,cmd = 't' ); + + end; + + 'C' ,'c' : + begin + arg[0 ]:=tok.last_number; + + for i:=1 to 5 do + arg[i ]:=tok.next(cmd ); + + curve4(arg[0 ] ,arg[1 ] ,arg[2 ] ,arg[3 ] ,arg[4 ] ,arg[5 ] ,cmd = 'c' ); + + end; + + 'S' ,'s' : + begin + arg[0 ]:=tok.last_number; + + for i:=1 to 3 do + arg[i ]:=tok.next(cmd ); + + curve4(arg[0 ] ,arg[1 ] ,arg[2 ] ,arg[3 ] ,cmd = 's' ); + + end; + + 'A' ,'a' : + raise svg_exception.Construct(PChar('parse_path: Command A: NOT IMPLEMENTED YET' ) ); + + 'Z' ,'z' : + close_subpath; + + else + begin + sprintf(@buf[0 ] ,'parse_path: Invalid Command %c' ,unsigned(cmd ) ); + + raise svg_exception.Construct(PChar(@buf[0 ] ) ); + + end; + + end; + + end; + +end; + +{ END_PATH } +procedure path_renderer.end_path; +var + idx : unsigned; + attr : path_attributes; + +begin + if m_attr_storage.size = 0 then + raise svg_exception(PChar('end_path : The path was not begun' ) ); + + attr.Construct(cur_attr ); + + idx :=path_attributes_ptr(m_attr_storage.array_operator(m_attr_storage.size - 1 ) ).index; + attr.index:=idx; + + move( + pointer(@attr )^ , + path_attributes_ptr(m_attr_storage.array_operator(m_attr_storage.size - 1 ) )^ , + sizeof(path_attributes ) ); + + pop_attr; + +end; + +{ MOVE_TO } +procedure path_renderer.move_to; +begin + if rel then + m_storage.rel_to_abs(@x ,@y ); + + m_storage.move_to(x ,y ); + +end; + +{ LINE_TO } +procedure path_renderer.line_to; +begin + if rel then + m_storage.rel_to_abs(@x ,@y ); + + m_storage.line_to(x ,y ); + +end; + +{ HLINE_TO } +procedure path_renderer.hline_to; +var + x2 ,y2 : double; + +begin + x2:=0.0; + y2:=0.0; + + if m_storage.total_vertices <> 0 then + begin + m_storage.vertex_(m_storage.total_vertices - 1 ,@x2 ,@y2 ); + + if rel then + x:=x + x2; + + m_storage.line_to(x ,y2 ); + + end; + +end; + +{ VLINE_TO } +procedure path_renderer.vline_to; +var + x2 ,y2 : double; + +begin + x2:=0.0; + y2:=0.0; + + if m_storage.total_vertices <> 0 then + begin + m_storage.vertex_(m_storage.total_vertices - 1 ,@x2 ,@y2 ); + + if rel then + y:=y + y2; + + m_storage.line_to(x2 ,y ); + + end; + +end; + +{ CURVE3 } +procedure path_renderer.curve3(x1 ,y1 ,x ,y : double; rel : boolean = false ); +begin + if rel then + begin + m_storage.rel_to_abs(@x1 ,@y1 ); + m_storage.rel_to_abs(@x ,@y ); + + end; + + m_storage.curve3(x1 ,y1 ,x ,y ); + +end; + +{ CURVE3 } +procedure path_renderer.curve3(x ,y : double; rel : boolean = false ); +begin +// raise exception("curve3(x, y) : NOT IMPLEMENTED YET"); + if rel then + m_storage.curve3_rel(x ,y ) + else + m_storage.curve3(x ,y ); + +end; + +{ CURVE4 } +procedure path_renderer.curve4(x1 ,y1 ,x2 ,y2 ,x ,y : double; rel : boolean = false ); +begin + if rel then + begin + m_storage.rel_to_abs(@x1 ,@y1 ); + m_storage.rel_to_abs(@x2 ,@y2 ); + m_storage.rel_to_abs(@x ,@y ); + + end; + + m_storage.curve4(x1 ,y1 ,x2 ,y2 ,x ,y ); + +end; + +{ CURVE4 } +procedure path_renderer.curve4(x2 ,y2 ,x ,y : double; rel : boolean = false ); +begin +//throw exception("curve4(x2, y2, x, y) : NOT IMPLEMENTED YET"); + if rel then + m_storage.curve4_rel(x2 ,y2 ,x ,y ) + else + m_storage.curve4(x2 ,y2 ,x ,y ); + +end; + +{ CLOSE_SUBPATH } +procedure path_renderer.close_subpath; +begin + m_storage.end_poly(path_flags_close ); + +end; + +{ ADD_PATH } +procedure path_renderer.add_path; +begin + m_storage.add_path(vs ,path_id ,solid_path ); + +end; + +{ VERTEX_COUNT } +function path_renderer.vertex_count; +begin + result:=m_curved_count._count; + +end; + +{ PUSH_ATTR } +procedure path_renderer.push_attr; +var + attr : path_attributes; + +begin + if m_attr_stack.size <> 0 then + m_attr_stack.add( + m_attr_stack.array_operator(m_attr_stack.size - 1 ) ) + else + begin + attr.Construct; + + m_attr_stack.add(@attr ); + + end; + +end; + +{ POP_ATTR } +procedure path_renderer.pop_attr; +begin + if m_attr_stack.size = 0 then + raise svg_exception(PChar('pop_attr : Attribute stack is empty' ) ); + + m_attr_stack.remove_last; + +end; + +{ FILL } +procedure path_renderer.fill; +var + attr : path_attributes_ptr; + +begin + attr:=cur_attr; + + attr.fill_color:=f^; + attr.fill_flag :=true; + +end; + +{ STROKE } +procedure path_renderer.stroke; +var + attr : path_attributes_ptr; + +begin + attr:=cur_attr; + + attr.stroke_color:=s^; + attr.stroke_flag :=true; + +end; + +{ EVEN_ODD } +procedure path_renderer.even_odd; +begin + cur_attr.even_odd_flag:=flag; + +end; + +{ STROKE_WIDTH } +procedure path_renderer.stroke_width; +var + attr : path_attributes_ptr; + +begin + attr:=cur_attr; + + attr.stroke_width:=w; + attr.stroke_flag :=true; + +end; + +{ FILL_NONE } +procedure path_renderer.fill_none; +begin + cur_attr.fill_flag:=false; + +end; + +{ STROKE_NONE } +procedure path_renderer.stroke_none; +begin + cur_attr.stroke_flag:=false; + +end; + +{ FILL_OPACITY } +procedure path_renderer.fill_opacity; +begin + cur_attr.fill_color.opacity_(op ); + +end; + +{ STROKE_OPACITY } +procedure path_renderer.stroke_opacity; +begin + cur_attr.stroke_color.opacity_(op ); + +end; + +{ LINE_JOIN } +procedure path_renderer.line_join; +begin + cur_attr.line_join:=join; + +end; + +{ LINE_CAP } +procedure path_renderer.line_cap; +begin + cur_attr.line_cap:=cap; + +end; + +{ MITER_LIMIT } +procedure path_renderer.miter_limit; +begin + cur_attr.miter_limit:=ml; + +end; + +{ TRANSFORM } +function path_renderer.transform; +begin + result:=@cur_attr.transform; + +end; + +{ ARRANGE_ORIENTATIONS } +procedure path_renderer.arrange_orientations; +begin + m_storage.arrange_orientations_all_paths(path_flags_ccw ); + +end; + +{ EXPAND } +procedure path_renderer.expand; +begin + m_curved_trans_contour.width_(value ); + +end; + +{ ARRAY_OPERATOR } +function path_renderer.array_operator; +begin + m_transform.assign_all( + @path_attributes_ptr( + m_attr_storage.array_operator(idx ) ).transform ); + + result:=path_attributes_ptr(m_attr_storage.array_operator(idx ) ).index; + +end; + +{ BOUNDING_RECT } +procedure path_renderer.bounding_rect; +var + trans : conv_transform; + +begin + trans.Construct(@m_storage ,@m_transform ); + + bounding_rect_ul( + @trans ,@self ,0 ,m_attr_storage.size ,x1 ,y1 ,x2 ,y2 ); + +end; + +{ RENDER } +procedure path_renderer.render; +var + i : unsigned; + + scl : double; + + attr : path_attributes_ptr; + + color : aggclr; + +begin + ras.clip_box (cb.x1 ,cb.y1 ,cb.x2 ,cb.y2 ); + m_curved_count.count_(0 ); + + i:=0; + + while i < m_attr_storage.size do + begin + attr:=path_attributes_ptr(m_attr_storage.array_operator(i ) ); + + m_transform.assign_all(@attr.transform ); + m_transform.multiply (mtx ); + + scl:=m_transform.scale; + + //m_curved.approximation_method(curve_inc ); + + m_curved.approximation_scale_(scl ); + m_curved.angle_tolerance_ (0.0 ); + + color.Construct; + + if attr.fill_flag then + begin + ras.reset; + + if attr.even_odd_flag then + ras.filling_rule(fill_even_odd ) + else + ras.filling_rule(fill_non_zero ); + + if Abs(m_curved_trans_contour._width ) < 0.0001 then + ras.add_path(@m_curved_trans ,attr.index ) + else + begin + m_curved_trans_contour.miter_limit_(attr.miter_limit ); + + ras.add_path(@m_curved_trans_contour ,attr.index ); + + end; + + color:=attr.fill_color; + + color.opacity_ (color._opacity * opacity ); + ren.color_ (@color ); + render_scanlines(ras ,sl ,ren ); + + end; + + if attr.stroke_flag then + begin + m_curved_stroked.width_(attr.stroke_width ); + + //m_curved_stroked.line_join_((attr.line_join == miter_join) ? miter_join_round : attr.line_join); + + m_curved_stroked.line_join_ (attr.line_join ); + m_curved_stroked.line_cap_ (attr.line_cap ); + m_curved_stroked.miter_limit_ (attr.miter_limit ); + m_curved_stroked.approximation_scale_(scl ); + + // If the *visual* line width is considerable we + // turn on processing of curve cusps. + //--------------------- + if attr.stroke_width * scl > 1.0 then + m_curved.angle_tolerance_(0.2 ); + + ras.reset; + ras.filling_rule(fill_non_zero ); + ras.add_path (@m_curved_stroked_trans ,attr.index ); + + color:=attr.stroke_color; + + color.opacity_ (color._opacity * opacity); + ren.color_ (@color ); + render_scanlines(ras ,sl ,ren ); + + end; + + inc(i ); + + end; + +end; + +{ CUR_ATTR } +function path_renderer.cur_attr; +begin + if m_attr_stack.size = 0 then + raise svg_exception.Construct(PChar('cur_attr : Attribute stack is empty' ) ); + + result:= + path_attributes_ptr( + m_attr_stack.array_operator(m_attr_stack.size - 1 ) ); + +end; + +END. + diff --git a/src/corelib/render/software/svg/agg_svg_path_tokenizer.pas b/src/corelib/render/software/svg/agg_svg_path_tokenizer.pas index e96df6a9..4e5d8c0d 100644 --- a/src/corelib/render/software/svg/agg_svg_path_tokenizer.pas +++ b/src/corelib/render/software/svg/agg_svg_path_tokenizer.pas @@ -1,325 +1,325 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 23.06.2006-Milano: ptrcomp adjustments
-// 24.04.2006-Milano: Unit port establishment
-//
-{ agg_svg_path_tokenizer.pas }
-unit
- agg_svg_path_tokenizer ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- agg_basics ,
- agg_svg_exception ;
-
-{ TYPES DEFINITION }
-const
- s_commands = '+-MmZzLlHhVvCcSsQqTtAaFfPp';
- s_numeric = '.Ee0123456789';
- s_separators = ' ,'#9#10#13;
-
-type
-// SVG path tokenizer.
-// Example:
-//
-// agg::svg::path_tokenizer tok;
-//
-// tok.set_str("M-122.304 84.285L-122.304 84.285 122.203 86.179 ");
-// while(tok.next())
-// {
-// printf("command='%c' number=%f\n",
-// tok.last_command(),
-// tok.last_number());
-// }
-//
-// The tokenizer does all the routine job of parsing the SVG paths.
-// It doesn't recognize any graphical primitives, it even doesn't know
-// anything about pairs of coordinates (X,Y). The purpose of this class
-// is to tokenize the numeric values and commands. SVG paths can
-// have single numeric values for Horizontal or Vertical line_to commands
-// as well as more than two coordinates (4 or 6) for Bezier curves
-// depending on the semantics of the command.
-// The behaviour is as follows:
-//
-// Each call to next() returns true if there's new command or new numeric
-// value or false when the path ends. How to interpret the result
-// depends on the sematics of the command. For example, command "C"
-// (cubic Bezier curve) implies 6 floating point numbers preceded by this
-// command. If the command assumes no arguments (like z or Z) the
-// the last_number() values won't change, that is, last_number() always
-// returns the last recognized numeric value, so does last_command().
- path_tokenizer_ptr = ^path_tokenizer;
- path_tokenizer = object
- m_separators_mask ,
- m_commands_mask ,
- m_numeric_mask : array[0..256 div 8 - 1 ] of char;
-
- m_path : char_ptr;
- m_last_number : double;
- m_last_command : char;
-
- constructor Construct;
-
- procedure set_path_str(str : char_ptr );
-
- function next : boolean; overload;
- function next(cmd : char ) : double; overload;
-
- function last_command : char;
- function last_number : double;
-
- procedure init_char_mask(mask ,char_set : char_ptr );
-
- function contains_ (mask : char_ptr; c : unsigned ) : boolean;
- function is_command (c : unsigned ) : boolean;
- function is_numeric (c : unsigned ) : boolean;
- function is_separator(c : unsigned ) : boolean;
- function parse_number : boolean;
-
- end;
-
-{ GLOBAL PROCEDURES }
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor path_tokenizer.Construct;
-begin
- m_path :=NIL;
- m_last_command:=#0;
- m_last_number :=0.0;
-
- init_char_mask(@m_commands_mask[0 ] ,@s_commands[1 ] );
- init_char_mask(@m_numeric_mask[0 ] ,@s_numeric[1 ] );
- init_char_mask(@m_separators_mask[0 ] ,@s_separators[1 ] );
-
-end;
-
-{ SET_PATH_STR }
-procedure path_tokenizer.set_path_str;
-begin
- m_path :=str;
- m_last_command:=#0;
- m_last_number :=0.0;
-
-end;
-
-{ NEXT }
-function path_tokenizer.next : boolean;
-var
- buf : array[0..99 ] of char;
-
-begin
- result:=false;
-
- if m_path = NIL then
- result:=false;
-
-// Skip all white spaces and other garbage
- while (m_path^ <> #0 ) and
- not is_command(unsigned(m_path^ ) ) and
- not is_numeric(unsigned(m_path^ ) ) do
- begin
- if not is_separator(unsigned(m_path^ ) ) then
- begin
- sprintf(@buf[0 ] ,'path_tokenizer::next : Invalid Character %c' ,unsigned(m_path^ ) );
-
- raise svg_exception.Construct(PChar(@buf[0 ] ) );
-
- end;
-
- inc(ptrcomp(m_path ) );
-
- end;
-
- if m_path^ = #0 then
- exit;
-
- if is_command(unsigned(m_path^ ) ) then
- begin
- // Check if the command is a numeric sign character
- if (m_path^ = '-' ) or
- (m_path^ = '+' ) then
- begin
- result:=parse_number;
-
- exit;
-
- end;
-
- m_last_command:=m_path^;
-
- inc(ptrcomp(m_path ) );
-
- while (m_path^ <> #0 ) and
- is_separator(unsigned(m_path^ ) ) do
- inc(ptrcomp(m_path ) );
-
- if m_path^ = #0 then
- begin
- result:=true;
-
- exit;
-
- end;
-
- end;
-
- result:=parse_number;
-
-end;
-
-{ NEXT }
-function path_tokenizer.next(cmd : char ) : double;
-var
- buf : array[0..99 ] of char;
-
-begin
- if not next then
- raise svg_exception.Construct(PChar('parse_path: Unexpected end of path' ) );
-
- if last_command <> cmd then
- begin
- sprintf(@buf[0 ] ,'parse_path: Command %c: bad or missing parameters' ,unsigned(cmd ) );
-
- raise svg_exception.Construct(PChar(@buf[0 ] ) );
-
- end;
-
- result:=last_number;
-
-end;
-
-{ LAST_COMMAND }
-function path_tokenizer.last_command;
-begin
- result:=m_last_command;
-
-end;
-
-{ LAST_NUMBER }
-function path_tokenizer.last_number;
-begin
- result:=m_last_number;
-
-end;
-
-{ INIT_CHAR_MASK }
-procedure path_tokenizer.init_char_mask;
-var
- c : unsigned;
-
-begin
- fillchar(mask^ ,256 div 8 ,0 );
-
- while char_set^ <> #0 do
- begin
- c:=int8u_ptr(char_set )^;
-
- int8u_ptr(ptrcomp(mask ) + (c shr 3 ) )^:=
- int8u_ptr(ptrcomp(mask ) + (c shr 3 ) )^ or (1 shl (c and 7 ) );
-
- inc(ptrcomp(char_set ) );
-
- end;
-
-end;
-
-{ CONTAINS_ }
-function path_tokenizer.contains_;
-begin
- result:=
- (int8u_ptr(ptrcomp(mask ) + (c shr 3 ) and (256 div 8 - 1 ) )^ and
- (1 shl (c and 7 ) ) ) <> 0;
-
-end;
-
-{ IS_COMMAND }
-function path_tokenizer.is_command;
-begin
- result:=contains_(@m_commands_mask[0 ] ,c );
-
-end;
-
-{ IS_NUMERIC }
-function path_tokenizer.is_numeric;
-begin
- result:=contains_(@m_numeric_mask[0 ] ,c );
-
-end;
-
-{ IS_SEPARATOR }
-function path_tokenizer.is_separator;
-begin
- result:=contains_(@m_separators_mask[0 ] ,c );
-
-end;
-
-{ PARSE_NUMBER }
-function path_tokenizer.parse_number;
-var
- buf : array[0..255 ] of char; // Should be enough for any number
-
- buf_ptr : char_ptr;
-
-begin
- buf_ptr:=@buf[0 ];
-
-// Copy all sign characters
- while (ptrcomp(buf_ptr ) < ptrcomp(@buf[0 ] ) + 255 ) and
- ((m_path^ = '-' ) or
- (m_path^ = '+' ) ) do
- begin
- buf_ptr^:=m_path^;
-
- inc(ptrcomp(buf_ptr ) );
- inc(ptrcomp(m_path ) );
-
- end;
-
-// Copy all numeric characters
- while (ptrcomp(buf_ptr ) < ptrcomp(@buf[0 ] ) + 255 ) and
- is_numeric(unsigned(m_path^ ) ) do
- begin
- buf_ptr^:=m_path^;
-
- inc(ptrcomp(buf_ptr ) );
- inc(ptrcomp(m_path ) );
-
- end;
-
- buf_ptr^:=#0;
-
- m_last_number:=get_double(pointer(PChar(@buf[0 ] ) ) );
-
- result:=true;
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 23.06.2006-Milano: ptrcomp adjustments +// 24.04.2006-Milano: Unit port establishment +// +{ agg_svg_path_tokenizer.pas } +unit + agg_svg_path_tokenizer ; + +INTERFACE + +{$I agg_mode.inc } + +uses + agg_basics , + agg_svg_exception ; + +{ TYPES DEFINITION } +const + s_commands = '+-MmZzLlHhVvCcSsQqTtAaFfPp'; + s_numeric = '.Ee0123456789'; + s_separators = ' ,'#9#10#13; + +type +// SVG path tokenizer. +// Example: +// +// agg::svg::path_tokenizer tok; +// +// tok.set_str("M-122.304 84.285L-122.304 84.285 122.203 86.179 "); +// while(tok.next()) +// { +// printf("command='%c' number=%f\n", +// tok.last_command(), +// tok.last_number()); +// } +// +// The tokenizer does all the routine job of parsing the SVG paths. +// It doesn't recognize any graphical primitives, it even doesn't know +// anything about pairs of coordinates (X,Y). The purpose of this class +// is to tokenize the numeric values and commands. SVG paths can +// have single numeric values for Horizontal or Vertical line_to commands +// as well as more than two coordinates (4 or 6) for Bezier curves +// depending on the semantics of the command. +// The behaviour is as follows: +// +// Each call to next() returns true if there's new command or new numeric +// value or false when the path ends. How to interpret the result +// depends on the sematics of the command. For example, command "C" +// (cubic Bezier curve) implies 6 floating point numbers preceded by this +// command. If the command assumes no arguments (like z or Z) the +// the last_number() values won't change, that is, last_number() always +// returns the last recognized numeric value, so does last_command(). + path_tokenizer_ptr = ^path_tokenizer; + path_tokenizer = object + m_separators_mask , + m_commands_mask , + m_numeric_mask : array[0..256 div 8 - 1 ] of char; + + m_path : char_ptr; + m_last_number : double; + m_last_command : char; + + constructor Construct; + + procedure set_path_str(str : char_ptr ); + + function next : boolean; overload; + function next(cmd : char ) : double; overload; + + function last_command : char; + function last_number : double; + + procedure init_char_mask(mask ,char_set : char_ptr ); + + function contains_ (mask : char_ptr; c : unsigned ) : boolean; + function is_command (c : unsigned ) : boolean; + function is_numeric (c : unsigned ) : boolean; + function is_separator(c : unsigned ) : boolean; + function parse_number : boolean; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor path_tokenizer.Construct; +begin + m_path :=NIL; + m_last_command:=#0; + m_last_number :=0.0; + + init_char_mask(@m_commands_mask[0 ] ,@s_commands[1 ] ); + init_char_mask(@m_numeric_mask[0 ] ,@s_numeric[1 ] ); + init_char_mask(@m_separators_mask[0 ] ,@s_separators[1 ] ); + +end; + +{ SET_PATH_STR } +procedure path_tokenizer.set_path_str; +begin + m_path :=str; + m_last_command:=#0; + m_last_number :=0.0; + +end; + +{ NEXT } +function path_tokenizer.next : boolean; +var + buf : array[0..99 ] of char; + +begin + result:=false; + + if m_path = NIL then + result:=false; + +// Skip all white spaces and other garbage + while (m_path^ <> #0 ) and + not is_command(unsigned(m_path^ ) ) and + not is_numeric(unsigned(m_path^ ) ) do + begin + if not is_separator(unsigned(m_path^ ) ) then + begin + sprintf(@buf[0 ] ,'path_tokenizer::next : Invalid Character %c' ,unsigned(m_path^ ) ); + + raise svg_exception.Construct(PChar(@buf[0 ] ) ); + + end; + + inc(ptrcomp(m_path ) ); + + end; + + if m_path^ = #0 then + exit; + + if is_command(unsigned(m_path^ ) ) then + begin + // Check if the command is a numeric sign character + if (m_path^ = '-' ) or + (m_path^ = '+' ) then + begin + result:=parse_number; + + exit; + + end; + + m_last_command:=m_path^; + + inc(ptrcomp(m_path ) ); + + while (m_path^ <> #0 ) and + is_separator(unsigned(m_path^ ) ) do + inc(ptrcomp(m_path ) ); + + if m_path^ = #0 then + begin + result:=true; + + exit; + + end; + + end; + + result:=parse_number; + +end; + +{ NEXT } +function path_tokenizer.next(cmd : char ) : double; +var + buf : array[0..99 ] of char; + +begin + if not next then + raise svg_exception.Construct(PChar('parse_path: Unexpected end of path' ) ); + + if last_command <> cmd then + begin + sprintf(@buf[0 ] ,'parse_path: Command %c: bad or missing parameters' ,unsigned(cmd ) ); + + raise svg_exception.Construct(PChar(@buf[0 ] ) ); + + end; + + result:=last_number; + +end; + +{ LAST_COMMAND } +function path_tokenizer.last_command; +begin + result:=m_last_command; + +end; + +{ LAST_NUMBER } +function path_tokenizer.last_number; +begin + result:=m_last_number; + +end; + +{ INIT_CHAR_MASK } +procedure path_tokenizer.init_char_mask; +var + c : unsigned; + +begin + fillchar(mask^ ,256 div 8 ,0 ); + + while char_set^ <> #0 do + begin + c:=int8u_ptr(char_set )^; + + int8u_ptr(ptrcomp(mask ) + (c shr 3 ) )^:= + int8u_ptr(ptrcomp(mask ) + (c shr 3 ) )^ or (1 shl (c and 7 ) ); + + inc(ptrcomp(char_set ) ); + + end; + +end; + +{ CONTAINS_ } +function path_tokenizer.contains_; +begin + result:= + (int8u_ptr(ptrcomp(mask ) + (c shr 3 ) and (256 div 8 - 1 ) )^ and + (1 shl (c and 7 ) ) ) <> 0; + +end; + +{ IS_COMMAND } +function path_tokenizer.is_command; +begin + result:=contains_(@m_commands_mask[0 ] ,c ); + +end; + +{ IS_NUMERIC } +function path_tokenizer.is_numeric; +begin + result:=contains_(@m_numeric_mask[0 ] ,c ); + +end; + +{ IS_SEPARATOR } +function path_tokenizer.is_separator; +begin + result:=contains_(@m_separators_mask[0 ] ,c ); + +end; + +{ PARSE_NUMBER } +function path_tokenizer.parse_number; +var + buf : array[0..255 ] of char; // Should be enough for any number + + buf_ptr : char_ptr; + +begin + buf_ptr:=@buf[0 ]; + +// Copy all sign characters + while (ptrcomp(buf_ptr ) < ptrcomp(@buf[0 ] ) + 255 ) and + ((m_path^ = '-' ) or + (m_path^ = '+' ) ) do + begin + buf_ptr^:=m_path^; + + inc(ptrcomp(buf_ptr ) ); + inc(ptrcomp(m_path ) ); + + end; + +// Copy all numeric characters + while (ptrcomp(buf_ptr ) < ptrcomp(@buf[0 ] ) + 255 ) and + is_numeric(unsigned(m_path^ ) ) do + begin + buf_ptr^:=m_path^; + + inc(ptrcomp(buf_ptr ) ); + inc(ptrcomp(m_path ) ); + + end; + + buf_ptr^:=#0; + + m_last_number:=get_double(pointer(PChar(@buf[0 ] ) ) ); + + result:=true; + +end; + +END. + diff --git a/src/corelib/render/software/util/agg_color_conv.pas b/src/corelib/render/software/util/agg_color_conv.pas index b00c590e..f73a3590 100644 --- a/src/corelib/render/software/util/agg_color_conv.pas +++ b/src/corelib/render/software/util/agg_color_conv.pas @@ -1,565 +1,565 @@ -//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4 (Public License)
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2005-2006
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-//----------------------------------------------------------------------------
-//
-// Conversion from one colorspace/pixel format to another
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 23.06.2006-Milano: ptrcomp adjustments
-// 16.12.2005-Milano: Unit port establishment
-//
-{ agg_color_conv.pas }
-unit
- agg_color_conv ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-uses
- agg_basics ,
- agg_color ,
- agg_rendering_buffer ;
-
-{ TYPES DEFINITION }
-type
- CopyRow = procedure(dst ,src : int8u_ptr; width : unsigned );
-
-{ GLOBAL PROCEDURES }
- procedure color_conv(dst ,src : rendering_buffer_ptr; copy_row_functor : CopyRow );
-
- procedure color_conv_gray8_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_gray8_to_rgb24 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_gray16_to_gray8 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_rgb555_to_rgb555(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgb555_to_rgb565(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgb555_to_rgb24 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgb555_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgb555_to_abgr32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgb555_to_argb32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgb555_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgb555_to_rgba32(dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_rgb565_to_rgb555(dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_bgr24_to_gray8 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_gray16 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_rgb555 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_rgb565 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_rgb24 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_abgr32 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_argb32 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_bgra32 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_rgba32 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_rgb48 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_bgr48 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_abgr64 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_argb64 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_bgra64 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgr24_to_rgba64 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_rgb24_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgb24_to_bgra32 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_bgra32_to_rgb555(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgra32_to_rgb565(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgra32_to_rgb24 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgra32_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgra32_to_abgr32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgra32_to_argb32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgra32_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgra32_to_rgba32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_bgra64_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_abgr32_to_argb32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_abgr32_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_abgr64_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_rgba32_to_argb32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_rgba32_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_argb32_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
- procedure color_conv_argb64_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_rgbAAA_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_bgrAAA_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_rgbBBA_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_bgrABB_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_rgb48_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_bgr48_to_bgr24 (dst ,src : int8u_ptr; width : unsigned );
-
- procedure color_conv_rgba64_to_bgra32(dst ,src : int8u_ptr; width : unsigned );
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-{ UNIT IMPLEMENTATION }
-{ COLOR_CONV }
-procedure color_conv;
-var
- y ,width ,height : unsigned;
-
-begin
- width :=src._width;
- height:=src._height;
-
- if dst._width < width then
- width:=dst._width;
-
- if dst._height < height then
- height:=dst._height;
-
- if width > 0 then
- for y:=0 to height - 1 do
- copy_row_functor(dst.row(y ) ,src.row(y ) ,width );
-
-end;
-
-{ color_conv_bgr24_to_gray8 {..}
-procedure color_conv_bgr24_to_gray8;
-begin
-end;
-
-{ color_conv_gray8_to_bgr24 }
-procedure color_conv_gray8_to_bgr24;
-begin
- repeat
- int8u_ptr(ptrcomp(dst ) + bgr_order.R )^:=src^;
- int8u_ptr(ptrcomp(dst ) + bgr_order.G )^:=src^;
- int8u_ptr(ptrcomp(dst ) + bgr_order.B )^:=src^;
-
- inc(ptrcomp(dst ) ,3 );
- inc(ptrcomp(src ) );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_gray8_to_rgb24 }
-procedure color_conv_gray8_to_rgb24;
-begin
- repeat
- int8u_ptr(ptrcomp(dst ) + rgb_order.R )^:=src^;
- int8u_ptr(ptrcomp(dst ) + rgb_order.G )^:=src^;
- int8u_ptr(ptrcomp(dst ) + rgb_order.B )^:=src^;
-
- inc(ptrcomp(dst ) ,3 );
- inc(ptrcomp(src ) );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_bgr24_to_gray16 {..}
-procedure color_conv_bgr24_to_gray16;
-begin
-end;
-
-{ color_conv_rgb555_to_rgb555 {..}
-procedure color_conv_rgb555_to_rgb555;
-begin
-end;
-
-{ color_conv_bgr24_to_rgb555 {..}
-procedure color_conv_bgr24_to_rgb555;
-begin
-end;
-
-{ color_conv_bgra32_to_rgb555 {..}
-procedure color_conv_bgra32_to_rgb555;
-begin
-end;
-
-{ color_conv_rgb555_to_rgb565 {..}
-procedure color_conv_rgb555_to_rgb565;
-begin
-end;
-
-{ color_conv_bgr24_to_rgb565 {..}
-procedure color_conv_bgr24_to_rgb565;
-begin
-end;
-
-{ color_conv_bgra32_to_rgb565 {..}
-procedure color_conv_bgra32_to_rgb565;
-begin
-end;
-
-{ color_conv_rgb555_to_rgb24 {..}
-procedure color_conv_rgb555_to_rgb24;
-begin
-end;
-
-{ color_conv_bgr24_to_rgb24 }
-procedure color_conv_bgr24_to_rgb24;
-begin
- repeat
- int8u_ptr(ptrcomp(dst ) + bgr_order.R )^:=int8u_ptr(ptrcomp(src ) + rgb_order.R )^;
- int8u_ptr(ptrcomp(dst ) + bgr_order.G )^:=int8u_ptr(ptrcomp(src ) + rgb_order.G )^;
- int8u_ptr(ptrcomp(dst ) + bgr_order.B )^:=int8u_ptr(ptrcomp(src ) + rgb_order.B )^;
-
- inc(ptrcomp(dst ) ,3 );
- inc(ptrcomp(src ) ,3 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_bgra32_to_rgb24 {..}
-procedure color_conv_bgra32_to_rgb24;
-begin
-end;
-
-{ color_conv_rgb555_to_bgr24 {..}
-procedure color_conv_rgb555_to_bgr24;
-begin
-end;
-
-{ color_conv_bgr24_to_bgr24 }
-procedure color_conv_bgr24_to_bgr24;
-begin
- move(src^ ,dst^ ,width * 3 );
-
-end;
-
-{ color_conv_bgra32_to_bgr24 {..}
-procedure color_conv_bgra32_to_bgr24;
-begin
-end;
-
-{ color_conv_bgr24_to_rgb48 {..}
-procedure color_conv_bgr24_to_rgb48;
-begin
-end;
-
-{ color_conv_bgr24_to_bgr48 {..}
-procedure color_conv_bgr24_to_bgr48;
-begin
-end;
-
-{ color_conv_rgb555_to_abgr32 {..}
-procedure color_conv_rgb555_to_abgr32;
-begin
-end;
-
-{ color_conv_bgr24_to_abgr32 {..}
-procedure color_conv_bgr24_to_abgr32;
-begin
-end;
-
-{ color_conv_bgra32_to_abgr32 {..}
-procedure color_conv_bgra32_to_abgr32;
-begin
-end;
-
-{ color_conv_rgb555_to_argb32 {..}
-procedure color_conv_rgb555_to_argb32;
-begin
-end;
-
-{ color_conv_bgr24_to_argb32 {..}
-procedure color_conv_bgr24_to_argb32;
-begin
-end;
-
-{ color_conv_bgra32_to_argb32 }
-procedure color_conv_bgra32_to_argb32;
-begin
- repeat
- int8u_ptr(ptrcomp(dst ) + argb_order.R )^:=int8u_ptr(ptrcomp(src ) + bgra_order.R )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.G )^:=int8u_ptr(ptrcomp(src ) + bgra_order.G )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.B )^:=int8u_ptr(ptrcomp(src ) + bgra_order.B )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.A )^:=int8u_ptr(ptrcomp(src ) + bgra_order.A )^;
-
- inc(ptrcomp(dst ) ,4 );
- inc(ptrcomp(src ) ,4 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_abgr32_to_argb32 }
-procedure color_conv_abgr32_to_argb32;
-begin
- repeat
- int8u_ptr(ptrcomp(dst ) + argb_order.R )^:=int8u_ptr(ptrcomp(src ) + abgr_order.R )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.G )^:=int8u_ptr(ptrcomp(src ) + abgr_order.G )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.B )^:=int8u_ptr(ptrcomp(src ) + abgr_order.B )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.A )^:=int8u_ptr(ptrcomp(src ) + abgr_order.A )^;
-
- inc(ptrcomp(dst ) ,4 );
- inc(ptrcomp(src ) ,4 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_rgba32_to_argb32 }
-procedure color_conv_rgba32_to_argb32;
-begin
- repeat
- int8u_ptr(ptrcomp(dst ) + argb_order.R )^:=int8u_ptr(ptrcomp(src ) + rgba_order.R )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.G )^:=int8u_ptr(ptrcomp(src ) + rgba_order.G )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.B )^:=int8u_ptr(ptrcomp(src ) + rgba_order.B )^;
- int8u_ptr(ptrcomp(dst ) + argb_order.A )^:=int8u_ptr(ptrcomp(src ) + rgba_order.A )^;
-
- inc(ptrcomp(dst ) ,4 );
- inc(ptrcomp(src ) ,4 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_rgb555_to_bgra32 {..}
-procedure color_conv_rgb555_to_bgra32;
-begin
-end;
-
-{ color_conv_bgr24_to_bgra32 }
-procedure color_conv_bgr24_to_bgra32;
-begin
- repeat
- int8u_ptr(ptrcomp(dst ) + 0 )^:=src^; inc(ptrcomp(src ) );
- int8u_ptr(ptrcomp(dst ) + 1 )^:=src^; inc(ptrcomp(src ) );
- int8u_ptr(ptrcomp(dst ) + 2 )^:=src^; inc(ptrcomp(src ) );
- int8u_ptr(ptrcomp(dst ) + 3 )^:=255;
-
- inc(ptrcomp(dst ) ,4 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_bgra32_to_bgra32 {..}
-procedure color_conv_bgra32_to_bgra32;
-begin
-end;
-
-{ color_conv_rgb555_to_rgba32 {..}
-procedure color_conv_rgb555_to_rgba32;
-begin
-end;
-
-{ color_conv_bgr24_to_rgba32 {..}
-procedure color_conv_bgr24_to_rgba32;
-begin
-end;
-
-{ color_conv_bgra32_to_rgba32 {..}
-procedure color_conv_bgra32_to_rgba32;
-begin
-end;
-
-{ color_conv_bgr24_to_abgr64 {..}
-procedure color_conv_bgr24_to_abgr64;
-begin
-end;
-
-{ color_conv_bgr24_to_argb64 {..}
-procedure color_conv_bgr24_to_argb64;
-begin
-end;
-
-{ color_conv_bgr24_to_bgra64 {..}
-procedure color_conv_bgr24_to_bgra64;
-begin
-end;
-
-{ color_conv_bgr24_to_rgba64 {..}
-procedure color_conv_bgr24_to_rgba64;
-begin
-end;
-
-{ color_conv_gray16_to_gray8 {..}
-procedure color_conv_gray16_to_gray8;
-begin
-end;
-
-{ color_conv_rgb565_to_rgb555 }
-procedure color_conv_rgb565_to_rgb555;
-var
- rgb : int;
-
-begin
- repeat
- rgb:=int16u(p32(src ).ptr^ );
-
- int16u(p32(dst ).ptr^ ):=((rgb shr 1 ) and $7FE0 ) or (rgb and $1F );
-
- inc(ptrcomp(src ) ,2 );
- inc(ptrcomp(dst ) ,2 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_rgbAAA_to_bgr24 {..}
-procedure color_conv_rgbAAA_to_bgr24;
-begin
-end;
-
-{ color_conv_bgrAAA_to_bgr24 {..}
-procedure color_conv_bgrAAA_to_bgr24;
-begin
-end;
-
-{ color_conv_rgbBBA_to_bgr24 {..}
-procedure color_conv_rgbBBA_to_bgr24;
-begin
-end;
-
-{ color_conv_bgrABB_to_bgr24 {..}
-procedure color_conv_bgrABB_to_bgr24;
-begin
-end;
-
-{ color_conv_rgb24_to_bgr24 }
-procedure color_conv_rgb24_to_bgr24;
-begin
- repeat
- int8u_ptr(p32(dst ).int + 0 )^:=int8u_ptr(p32(src ).int + 2 )^;
- int8u_ptr(p32(dst ).int + 1 )^:=int8u_ptr(p32(src ).int + 1 )^;
- int8u_ptr(p32(dst ).int + 2 )^:=int8u_ptr(p32(src ).int + 0 )^;
-
- inc(ptrcomp(src ) ,3 );
- inc(ptrcomp(dst ) ,3 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_rgb48_to_bgr24 {..}
-procedure color_conv_rgb48_to_bgr24;
-begin
-end;
-
-{ color_conv_bgr48_to_bgr24 {..}
-procedure color_conv_bgr48_to_bgr24;
-begin
-end;
-
-{ color_conv_abgr32_to_bgra32 }
-procedure color_conv_abgr32_to_bgra32;
-begin
- repeat
- int8u_ptr(p32(dst ).int + 0 )^:=int8u_ptr(p32(src ).int + 1 )^;
- int8u_ptr(p32(dst ).int + 1 )^:=int8u_ptr(p32(src ).int + 2 )^;
- int8u_ptr(p32(dst ).int + 2 )^:=int8u_ptr(p32(src ).int + 3 )^;
- int8u_ptr(p32(dst ).int + 3 )^:=int8u_ptr(p32(src ).int + 0 )^;
-
- inc(ptrcomp(src ) ,4 );
- inc(ptrcomp(dst ) ,4 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_argb32_to_bgra32 }
-procedure color_conv_argb32_to_bgra32;
-begin
- repeat
- int8u_ptr(p32(dst ).int + 0 )^:=int8u_ptr(p32(src ).int + 3 )^;
- int8u_ptr(p32(dst ).int + 1 )^:=int8u_ptr(p32(src ).int + 2 )^;
- int8u_ptr(p32(dst ).int + 2 )^:=int8u_ptr(p32(src ).int + 1 )^;
- int8u_ptr(p32(dst ).int + 3 )^:=int8u_ptr(p32(src ).int + 0 )^;
-
- inc(ptrcomp(src ) ,4 );
- inc(ptrcomp(dst ) ,4 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_rgba32_to_bgra32 }
-procedure color_conv_rgba32_to_bgra32;
-begin
- repeat
- int8u_ptr(p32(dst ).int + 0 )^:=int8u_ptr(p32(src ).int + 2 )^;
- int8u_ptr(p32(dst ).int + 1 )^:=int8u_ptr(p32(src ).int + 1 )^;
- int8u_ptr(p32(dst ).int + 2 )^:=int8u_ptr(p32(src ).int + 0 )^;
- int8u_ptr(p32(dst ).int + 3 )^:=int8u_ptr(p32(src ).int + 3 )^;
-
- inc(ptrcomp(src ) ,4 );
- inc(ptrcomp(dst ) ,4 );
- dec(width );
-
- until width = 0;
-
-end;
-
-{ color_conv_bgra64_to_bgra32 {..}
-procedure color_conv_bgra64_to_bgra32;
-begin
-end;
-
-{ color_conv_abgr64_to_bgra32 {..}
-procedure color_conv_abgr64_to_bgra32;
-begin
-end;
-
-{ color_conv_argb64_to_bgra32 {..}
-procedure color_conv_argb64_to_bgra32;
-begin
-end;
-
-{ color_conv_rgba64_to_bgra32 {..}
-procedure color_conv_rgba64_to_bgra32;
-begin
-end;
-
-{ color_conv_rgb24_to_bgra32 }
-procedure color_conv_rgb24_to_bgra32;
-begin
- repeat
- int8u_ptr(ptrcomp(dst ) + bgra_order.R )^:=src^; inc(ptrcomp(src ) );
- int8u_ptr(ptrcomp(dst ) + bgra_order.G )^:=src^; inc(ptrcomp(src ) );
- int8u_ptr(ptrcomp(dst ) + bgra_order.B )^:=src^; inc(ptrcomp(src ) );
- int8u_ptr(ptrcomp(dst ) + bgra_order.A )^:=255;
-
- inc(ptrcomp(dst ) ,4 );
- dec(width );
-
- until width = 0;
-
-end;
-
-END.
-
+//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +//---------------------------------------------------------------------------- +// +// Conversion from one colorspace/pixel format to another +// +// [Pascal Port History] ----------------------------------------------------- +// +// 23.06.2006-Milano: ptrcomp adjustments +// 16.12.2005-Milano: Unit port establishment +// +{ agg_color_conv.pas } +unit + agg_color_conv ; + +INTERFACE + +{$I agg_mode.inc } + +uses + agg_basics , + agg_color , + agg_rendering_buffer ; + +{ TYPES DEFINITION } +type + CopyRow = procedure(dst ,src : int8u_ptr; width : unsigned ); + +{ GLOBAL PROCEDURES } + procedure color_conv(dst ,src : rendering_buffer_ptr; copy_row_functor : CopyRow ); + + procedure color_conv_gray8_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_gray8_to_rgb24 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_gray16_to_gray8 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_rgb555_to_rgb555(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgb555_to_rgb565(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgb555_to_rgb24 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgb555_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgb555_to_abgr32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgb555_to_argb32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgb555_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgb555_to_rgba32(dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_rgb565_to_rgb555(dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_bgr24_to_gray8 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_gray16 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_rgb555 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_rgb565 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_rgb24 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_abgr32 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_argb32 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_bgra32 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_rgba32 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_rgb48 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_bgr48 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_abgr64 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_argb64 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_bgra64 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgr24_to_rgba64 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_rgb24_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgb24_to_bgra32 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_bgra32_to_rgb555(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgra32_to_rgb565(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgra32_to_rgb24 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgra32_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgra32_to_abgr32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgra32_to_argb32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgra32_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgra32_to_rgba32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_bgra64_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_abgr32_to_argb32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_abgr32_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_abgr64_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_rgba32_to_argb32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_rgba32_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_argb32_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + procedure color_conv_argb64_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_rgbAAA_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_bgrAAA_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_rgbBBA_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_bgrABB_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_rgb48_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_bgr48_to_bgr24 (dst ,src : int8u_ptr; width : unsigned ); + + procedure color_conv_rgba64_to_bgra32(dst ,src : int8u_ptr; width : unsigned ); + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ COLOR_CONV } +procedure color_conv; +var + y ,width ,height : unsigned; + +begin + width :=src._width; + height:=src._height; + + if dst._width < width then + width:=dst._width; + + if dst._height < height then + height:=dst._height; + + if width > 0 then + for y:=0 to height - 1 do + copy_row_functor(dst.row(y ) ,src.row(y ) ,width ); + +end; + +{ color_conv_bgr24_to_gray8 {..} +procedure color_conv_bgr24_to_gray8; +begin +end; + +{ color_conv_gray8_to_bgr24 } +procedure color_conv_gray8_to_bgr24; +begin + repeat + int8u_ptr(ptrcomp(dst ) + bgr_order.R )^:=src^; + int8u_ptr(ptrcomp(dst ) + bgr_order.G )^:=src^; + int8u_ptr(ptrcomp(dst ) + bgr_order.B )^:=src^; + + inc(ptrcomp(dst ) ,3 ); + inc(ptrcomp(src ) ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_gray8_to_rgb24 } +procedure color_conv_gray8_to_rgb24; +begin + repeat + int8u_ptr(ptrcomp(dst ) + rgb_order.R )^:=src^; + int8u_ptr(ptrcomp(dst ) + rgb_order.G )^:=src^; + int8u_ptr(ptrcomp(dst ) + rgb_order.B )^:=src^; + + inc(ptrcomp(dst ) ,3 ); + inc(ptrcomp(src ) ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_bgr24_to_gray16 {..} +procedure color_conv_bgr24_to_gray16; +begin +end; + +{ color_conv_rgb555_to_rgb555 {..} +procedure color_conv_rgb555_to_rgb555; +begin +end; + +{ color_conv_bgr24_to_rgb555 {..} +procedure color_conv_bgr24_to_rgb555; +begin +end; + +{ color_conv_bgra32_to_rgb555 {..} +procedure color_conv_bgra32_to_rgb555; +begin +end; + +{ color_conv_rgb555_to_rgb565 {..} +procedure color_conv_rgb555_to_rgb565; +begin +end; + +{ color_conv_bgr24_to_rgb565 {..} +procedure color_conv_bgr24_to_rgb565; +begin +end; + +{ color_conv_bgra32_to_rgb565 {..} +procedure color_conv_bgra32_to_rgb565; +begin +end; + +{ color_conv_rgb555_to_rgb24 {..} +procedure color_conv_rgb555_to_rgb24; +begin +end; + +{ color_conv_bgr24_to_rgb24 } +procedure color_conv_bgr24_to_rgb24; +begin + repeat + int8u_ptr(ptrcomp(dst ) + bgr_order.R )^:=int8u_ptr(ptrcomp(src ) + rgb_order.R )^; + int8u_ptr(ptrcomp(dst ) + bgr_order.G )^:=int8u_ptr(ptrcomp(src ) + rgb_order.G )^; + int8u_ptr(ptrcomp(dst ) + bgr_order.B )^:=int8u_ptr(ptrcomp(src ) + rgb_order.B )^; + + inc(ptrcomp(dst ) ,3 ); + inc(ptrcomp(src ) ,3 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_bgra32_to_rgb24 {..} +procedure color_conv_bgra32_to_rgb24; +begin +end; + +{ color_conv_rgb555_to_bgr24 {..} +procedure color_conv_rgb555_to_bgr24; +begin +end; + +{ color_conv_bgr24_to_bgr24 } +procedure color_conv_bgr24_to_bgr24; +begin + move(src^ ,dst^ ,width * 3 ); + +end; + +{ color_conv_bgra32_to_bgr24 {..} +procedure color_conv_bgra32_to_bgr24; +begin +end; + +{ color_conv_bgr24_to_rgb48 {..} +procedure color_conv_bgr24_to_rgb48; +begin +end; + +{ color_conv_bgr24_to_bgr48 {..} +procedure color_conv_bgr24_to_bgr48; +begin +end; + +{ color_conv_rgb555_to_abgr32 {..} +procedure color_conv_rgb555_to_abgr32; +begin +end; + +{ color_conv_bgr24_to_abgr32 {..} +procedure color_conv_bgr24_to_abgr32; +begin +end; + +{ color_conv_bgra32_to_abgr32 {..} +procedure color_conv_bgra32_to_abgr32; +begin +end; + +{ color_conv_rgb555_to_argb32 {..} +procedure color_conv_rgb555_to_argb32; +begin +end; + +{ color_conv_bgr24_to_argb32 {..} +procedure color_conv_bgr24_to_argb32; +begin +end; + +{ color_conv_bgra32_to_argb32 } +procedure color_conv_bgra32_to_argb32; +begin + repeat + int8u_ptr(ptrcomp(dst ) + argb_order.R )^:=int8u_ptr(ptrcomp(src ) + bgra_order.R )^; + int8u_ptr(ptrcomp(dst ) + argb_order.G )^:=int8u_ptr(ptrcomp(src ) + bgra_order.G )^; + int8u_ptr(ptrcomp(dst ) + argb_order.B )^:=int8u_ptr(ptrcomp(src ) + bgra_order.B )^; + int8u_ptr(ptrcomp(dst ) + argb_order.A )^:=int8u_ptr(ptrcomp(src ) + bgra_order.A )^; + + inc(ptrcomp(dst ) ,4 ); + inc(ptrcomp(src ) ,4 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_abgr32_to_argb32 } +procedure color_conv_abgr32_to_argb32; +begin + repeat + int8u_ptr(ptrcomp(dst ) + argb_order.R )^:=int8u_ptr(ptrcomp(src ) + abgr_order.R )^; + int8u_ptr(ptrcomp(dst ) + argb_order.G )^:=int8u_ptr(ptrcomp(src ) + abgr_order.G )^; + int8u_ptr(ptrcomp(dst ) + argb_order.B )^:=int8u_ptr(ptrcomp(src ) + abgr_order.B )^; + int8u_ptr(ptrcomp(dst ) + argb_order.A )^:=int8u_ptr(ptrcomp(src ) + abgr_order.A )^; + + inc(ptrcomp(dst ) ,4 ); + inc(ptrcomp(src ) ,4 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_rgba32_to_argb32 } +procedure color_conv_rgba32_to_argb32; +begin + repeat + int8u_ptr(ptrcomp(dst ) + argb_order.R )^:=int8u_ptr(ptrcomp(src ) + rgba_order.R )^; + int8u_ptr(ptrcomp(dst ) + argb_order.G )^:=int8u_ptr(ptrcomp(src ) + rgba_order.G )^; + int8u_ptr(ptrcomp(dst ) + argb_order.B )^:=int8u_ptr(ptrcomp(src ) + rgba_order.B )^; + int8u_ptr(ptrcomp(dst ) + argb_order.A )^:=int8u_ptr(ptrcomp(src ) + rgba_order.A )^; + + inc(ptrcomp(dst ) ,4 ); + inc(ptrcomp(src ) ,4 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_rgb555_to_bgra32 {..} +procedure color_conv_rgb555_to_bgra32; +begin +end; + +{ color_conv_bgr24_to_bgra32 } +procedure color_conv_bgr24_to_bgra32; +begin + repeat + int8u_ptr(ptrcomp(dst ) + 0 )^:=src^; inc(ptrcomp(src ) ); + int8u_ptr(ptrcomp(dst ) + 1 )^:=src^; inc(ptrcomp(src ) ); + int8u_ptr(ptrcomp(dst ) + 2 )^:=src^; inc(ptrcomp(src ) ); + int8u_ptr(ptrcomp(dst ) + 3 )^:=255; + + inc(ptrcomp(dst ) ,4 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_bgra32_to_bgra32 {..} +procedure color_conv_bgra32_to_bgra32; +begin +end; + +{ color_conv_rgb555_to_rgba32 {..} +procedure color_conv_rgb555_to_rgba32; +begin +end; + +{ color_conv_bgr24_to_rgba32 {..} +procedure color_conv_bgr24_to_rgba32; +begin +end; + +{ color_conv_bgra32_to_rgba32 {..} +procedure color_conv_bgra32_to_rgba32; +begin +end; + +{ color_conv_bgr24_to_abgr64 {..} +procedure color_conv_bgr24_to_abgr64; +begin +end; + +{ color_conv_bgr24_to_argb64 {..} +procedure color_conv_bgr24_to_argb64; +begin +end; + +{ color_conv_bgr24_to_bgra64 {..} +procedure color_conv_bgr24_to_bgra64; +begin +end; + +{ color_conv_bgr24_to_rgba64 {..} +procedure color_conv_bgr24_to_rgba64; +begin +end; + +{ color_conv_gray16_to_gray8 {..} +procedure color_conv_gray16_to_gray8; +begin +end; + +{ color_conv_rgb565_to_rgb555 } +procedure color_conv_rgb565_to_rgb555; +var + rgb : int; + +begin + repeat + rgb:=int16u(p32(src ).ptr^ ); + + int16u(p32(dst ).ptr^ ):=((rgb shr 1 ) and $7FE0 ) or (rgb and $1F ); + + inc(ptrcomp(src ) ,2 ); + inc(ptrcomp(dst ) ,2 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_rgbAAA_to_bgr24 {..} +procedure color_conv_rgbAAA_to_bgr24; +begin +end; + +{ color_conv_bgrAAA_to_bgr24 {..} +procedure color_conv_bgrAAA_to_bgr24; +begin +end; + +{ color_conv_rgbBBA_to_bgr24 {..} +procedure color_conv_rgbBBA_to_bgr24; +begin +end; + +{ color_conv_bgrABB_to_bgr24 {..} +procedure color_conv_bgrABB_to_bgr24; +begin +end; + +{ color_conv_rgb24_to_bgr24 } +procedure color_conv_rgb24_to_bgr24; +begin + repeat + int8u_ptr(p32(dst ).int + 0 )^:=int8u_ptr(p32(src ).int + 2 )^; + int8u_ptr(p32(dst ).int + 1 )^:=int8u_ptr(p32(src ).int + 1 )^; + int8u_ptr(p32(dst ).int + 2 )^:=int8u_ptr(p32(src ).int + 0 )^; + + inc(ptrcomp(src ) ,3 ); + inc(ptrcomp(dst ) ,3 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_rgb48_to_bgr24 {..} +procedure color_conv_rgb48_to_bgr24; +begin +end; + +{ color_conv_bgr48_to_bgr24 {..} +procedure color_conv_bgr48_to_bgr24; +begin +end; + +{ color_conv_abgr32_to_bgra32 } +procedure color_conv_abgr32_to_bgra32; +begin + repeat + int8u_ptr(p32(dst ).int + 0 )^:=int8u_ptr(p32(src ).int + 1 )^; + int8u_ptr(p32(dst ).int + 1 )^:=int8u_ptr(p32(src ).int + 2 )^; + int8u_ptr(p32(dst ).int + 2 )^:=int8u_ptr(p32(src ).int + 3 )^; + int8u_ptr(p32(dst ).int + 3 )^:=int8u_ptr(p32(src ).int + 0 )^; + + inc(ptrcomp(src ) ,4 ); + inc(ptrcomp(dst ) ,4 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_argb32_to_bgra32 } +procedure color_conv_argb32_to_bgra32; +begin + repeat + int8u_ptr(p32(dst ).int + 0 )^:=int8u_ptr(p32(src ).int + 3 )^; + int8u_ptr(p32(dst ).int + 1 )^:=int8u_ptr(p32(src ).int + 2 )^; + int8u_ptr(p32(dst ).int + 2 )^:=int8u_ptr(p32(src ).int + 1 )^; + int8u_ptr(p32(dst ).int + 3 )^:=int8u_ptr(p32(src ).int + 0 )^; + + inc(ptrcomp(src ) ,4 ); + inc(ptrcomp(dst ) ,4 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_rgba32_to_bgra32 } +procedure color_conv_rgba32_to_bgra32; +begin + repeat + int8u_ptr(p32(dst ).int + 0 )^:=int8u_ptr(p32(src ).int + 2 )^; + int8u_ptr(p32(dst ).int + 1 )^:=int8u_ptr(p32(src ).int + 1 )^; + int8u_ptr(p32(dst ).int + 2 )^:=int8u_ptr(p32(src ).int + 0 )^; + int8u_ptr(p32(dst ).int + 3 )^:=int8u_ptr(p32(src ).int + 3 )^; + + inc(ptrcomp(src ) ,4 ); + inc(ptrcomp(dst ) ,4 ); + dec(width ); + + until width = 0; + +end; + +{ color_conv_bgra64_to_bgra32 {..} +procedure color_conv_bgra64_to_bgra32; +begin +end; + +{ color_conv_abgr64_to_bgra32 {..} +procedure color_conv_abgr64_to_bgra32; +begin +end; + +{ color_conv_argb64_to_bgra32 {..} +procedure color_conv_argb64_to_bgra32; +begin +end; + +{ color_conv_rgba64_to_bgra32 {..} +procedure color_conv_rgba64_to_bgra32; +begin +end; + +{ color_conv_rgb24_to_bgra32 } +procedure color_conv_rgb24_to_bgra32; +begin + repeat + int8u_ptr(ptrcomp(dst ) + bgra_order.R )^:=src^; inc(ptrcomp(src ) ); + int8u_ptr(ptrcomp(dst ) + bgra_order.G )^:=src^; inc(ptrcomp(src ) ); + int8u_ptr(ptrcomp(dst ) + bgra_order.B )^:=src^; inc(ptrcomp(src ) ); + int8u_ptr(ptrcomp(dst ) + bgra_order.A )^:=255; + + inc(ptrcomp(dst ) ,4 ); + dec(width ); + + until width = 0; + +end; + +END. + diff --git a/tools/wipfc/entit932.txt b/tools/wipfc/entit932.txt index 37687201..de2bcd2e 100644 --- a/tools/wipfc/entit932.txt +++ b/tools/wipfc/entit932.txt @@ -1,202 +1,202 @@ --&mdash.
--&ndash.
- &rbl.
-!&xclm.
-!&xclam.
-"&cdq.
-"&odq.
-#&numsign.
-$&dollar.
-%&percent.
-&&.
-'&apos.
-'&csq.
-`&osq.
-`&grave.
-(&lpar.
-(&lparen.
-)&rpar.
-)&rparen.
-*&asterisk.
-.&period.
-+&plus.
-,&comma.
--&dash.
--&emdash.
--&endash.
--&hyphen.
--&minus.
-.&per.
-/&slash.
-/&slr.
-:&colon.
-;&semi.
->>.
->>sym.
-=&eq.
-=&equals.
-=&eqsym.
-<<.
-<<sym.
-@&atsign.
-{&lbrace.
-{&lbrc.
-|&splitvbar.
-|&vbar.
-|&lor.
-}&rbrace.
-}&rbrc.
-[&lbracket.
-[&lbrk.
-\&bslash.
-\&bsl.
-]&rbracket.
-]&rbrk.
-^&caret.
-^&and.
-_&us.
-~&tilde.
-~&similar.
- &house.
-C&Cc.
-u&ue.
-e&ea.
-a&ac.
-a&ae.
-a&ag.
-a&ao.
-c&cc.
-e&ec.
-e&ee.
-e&eg.
-i&ie.
-i&ic.
-i&ig.
-A&Ae.
-A&Ao.
-&angstrom.
-E&Ea.
- æ.
- Æ.
-o&oc.
-o&oe.
-o&og.
-u&uc.
-u&ug.
-y&ye.
-O&Oe.
-U&Ue.
-¢.
-&Lsterling.
-\¥.
-f&fnof.
-a&aa.
-i&ia.
-o&oa.
-u&ua.
-n&nt.
-N&Nt.
-a&aus.
-o&ous.
- &invq.
- &lnotrev.
-T&lnot.
-T¬sym.
-1/2½.
-1/4¼.
- &inve.
-s&odqf.
-t&cdqf.
-&alpha.
-@&Alpha.
-B&Beta.
-C&Gamma.
-&pi.
-&Sigma.
-&sigma.
-&mu.
-&tau.
-U&Phi.
-&Theta.
-&Omega.
-&delta.
-&infinity.
-&phi.
-&epsilon.
-&intersect.
-&identical.
-}&plusmin.
-}&pm.
-&ge.
-&gesym.
-&le.
-&lesym.
- &inttop.
- &intbot.
-÷.
-&nearly.
-°ree.
-°.
-&bullet.
-&dot.
-&sqrt.
-n&supn.
-2².
-&sqbul.
-&box14.
-&box12.
-&box34.
-&bx1012.
-&bx2021.
-&bx0021.
-&bx0012.
-&bx2022.
-&bx2020.
-&bx0022.
-&bx2002.
-&bx2001.
-&bx1002.
-&bx1210.
-&bx2120.
-&bx2200.
-&bx0220.
-&bx2202.
-&bx0222.
-&bx2220.
-&bx0202.
-&bx2222.
-&bx1202.
-&bx1201.
-&bx0212.
-&bx0121.
-&bx2100.
-&bx1200.
-&bx0210.
-&bx0120.
-&bx2121.
-&bx1212.
-&bxas.
-&bxbj.
-&bxcr.
-&bxcj.
-&bxde.
-&bxtj.
-&bxh.
-&bxll.
-&bxlr.
-&bxri.
-&bxrj.
-&bxul.
-&bxur.
-&bxv.
- &BOX.
- &BOXBOT.
- &BOXLEFT.
- &BOXRIGHT.
- &BOXTOP.
-&darrow.
-&uarrow.
-&larrow.
-&rarrow.
->&rahead.
+-&mdash. +-&ndash. + &rbl. +!&xclm. +!&xclam. +"&cdq. +"&odq. +#&numsign. +$&dollar. +%&percent. +&&. +'&apos. +'&csq. +`&osq. +`&grave. +(&lpar. +(&lparen. +)&rpar. +)&rparen. +*&asterisk. +.&period. ++&plus. +,&comma. +-&dash. +-&emdash. +-&endash. +-&hyphen. +-&minus. +.&per. +/&slash. +/&slr. +:&colon. +;&semi. +>>. +>>sym. +=&eq. +=&equals. +=&eqsym. +<<. +<<sym. +@&atsign. +{&lbrace. +{&lbrc. +|&splitvbar. +|&vbar. +|&lor. +}&rbrace. +}&rbrc. +[&lbracket. +[&lbrk. +\&bslash. +\&bsl. +]&rbracket. +]&rbrk. +^&caret. +^&and. +_&us. +~&tilde. +~&similar. + &house. +C&Cc. +u&ue. +e&ea. +a&ac. +a&ae. +a&ag. +a&ao. +c&cc. +e&ec. +e&ee. +e&eg. +i&ie. +i&ic. +i&ig. +A&Ae. +A&Ao. +&angstrom. +E&Ea. + æ. + Æ. +o&oc. +o&oe. +o&og. +u&uc. +u&ug. +y&ye. +O&Oe. +U&Ue. +¢. +&Lsterling. +\¥. +f&fnof. +a&aa. +i&ia. +o&oa. +u&ua. +n&nt. +N&Nt. +a&aus. +o&ous. + &invq. + &lnotrev. +T&lnot. +T¬sym. +1/2½. +1/4¼. + &inve. +s&odqf. +t&cdqf. +&alpha. +@&Alpha. +B&Beta. +C&Gamma. +&pi. +&Sigma. +&sigma. +&mu. +&tau. +U&Phi. +&Theta. +&Omega. +&delta. +&infinity. +&phi. +&epsilon. +&intersect. +&identical. +}&plusmin. +}&pm. +&ge. +&gesym. +&le. +&lesym. + &inttop. + &intbot. +÷. +&nearly. +°ree. +°. +&bullet. +&dot. +&sqrt. +n&supn. +2². +&sqbul. +&box14. +&box12. +&box34. +&bx1012. +&bx2021. +&bx0021. +&bx0012. +&bx2022. +&bx2020. +&bx0022. +&bx2002. +&bx2001. +&bx1002. +&bx1210. +&bx2120. +&bx2200. +&bx0220. +&bx2202. +&bx0222. +&bx2220. +&bx0202. +&bx2222. +&bx1202. +&bx1201. +&bx0212. +&bx0121. +&bx2100. +&bx1200. +&bx0210. +&bx0120. +&bx2121. +&bx1212. +&bxas. +&bxbj. +&bxcr. +&bxcj. +&bxde. +&bxtj. +&bxh. +&bxll. +&bxlr. +&bxri. +&bxrj. +&bxul. +&bxur. +&bxv. + &BOX. + &BOXBOT. + &BOXLEFT. + &BOXRIGHT. + &BOXTOP. +&darrow. +&uarrow. +&larrow. +&rarrow. +>&rahead.
\ No newline at end of file diff --git a/tools/wipfc/entit934.txt b/tools/wipfc/entit934.txt index 8d19825f..a6104d13 100644 --- a/tools/wipfc/entit934.txt +++ b/tools/wipfc/entit934.txt @@ -1,201 +1,201 @@ --&mdash.
--&ndash.
- &rbl.
-!&xclm.
-!&xclam.
-"&cdq.
-"&odq.
-#&numsign.
-$&dollar.
-%&percent.
-&&.
-'&apos.
-'&csq.
-`&osq.
-`&grave.
-(&lpar.
-(&lparen.
-)&rpar.
-)&rparen.
-*&asterisk.
-.&period.
-+&plus.
-,&comma.
--&dash.
--&emdash.
--&endash.
--&hyphen.
--&minus.
-.&per.
-/&slash.
-/&slr.
-:&colon.
-;&semi.
->>.
->>sym.
-=&eq.
-=&equals.
-=&eqsym.
-<<.
-<<sym.
-@&atsign.
-{&lbrace.
-{&lbrc.
-|&splitvbar.
-|&vbar.
-|&lor.
-}&rbrace.
-}&rbrc.
-[&lbracket.
-[&lbrk.
-\&bslash.
-\&bsl.
-]&rbracket.
-]&rbrk.
-^&caret.
-^&and.
-_&us.
-~&tilde.
-~&similar.
-&house.
-&Cc.
-&ue.
-&ea.
-&ac.
-&ae.
-&ag.
-&ao.
-&cc.
-&ec.
-&ee.
-&eg.
-&ie.
-&ic.
-&ig.
-&Ae.
-&Ao.
-&angstrom.
-&Ea.
-æ.
-Æ.
-&oc.
-&oe.
-&og.
-&uc.
-&ug.
-&ye.
-&Oe.
-&Ue.
-¢.
-&Lsterling.
-¥.
-&fnof.
-&aa.
-&ia.
-&oa.
-&ua.
-&nt.
-&Nt.
-&aus.
-&ous.
-&invq.
-&lnotrev.
-&lnot.
-¬sym.
-½.
-¼.
-&inve.
-&odqf.
-&cdqf.
-&alpha.
-A&Alpha.
-&Beta.
-&Gamma.
-&pi.
-&Sigma.
-&sigma.
-&mu.
-&tau.
-&Phi.
-&Theta.
-&Omega.
-&delta.
-&infinity.
-&phi.
-&epsilon.
-&intersect.
-&identical.
-&plusmin.
-&pm.
-&ge.
-&gesym.
-&le.
-&lesym.
-&inttop.
-&intbot.
-÷.
-&nearly.
-°ree.
-°.
-&bullet.
-&dot.
-&sqrt.
-&supn.
-².
-&sqbul.
-&box14.
-&box12.
-&box34.
-&bx1012.
-&bx2021.
-&bx0021.
-&bx0012.
-&bx2022.
-&bx2020.
-&bx0022.
-&bx2002.
-&bx2001.
-&bx1002.
-&bx1210.
-&bx2120.
-&bx2200.
-&bx0220.
-&bx2202.
-&bx0222.
-&bx2220.
-&bx0202.
-&bx2222.
-&bx1202.
-&bx1201.
-&bx0212.
-&bx0121.
-&bx2100.
-&bx1200.
-&bx0210.
-&bx0120.
-&bx2121.
-&bx1212.
-&bxas.
-&bxbj.
-&bxcr.
-&bxcj.
-&bxde.
-&bxtj.
-&bxh.
-&bxll.
-&bxlr.
-&bxri.
-&bxrj.
-&bxul.
-&bxur.
-&bxv.
-&BOX.
-&BOXBOT.
-&BOXLEFT.
-&BOXRIGHT.
-&BOXTOP.
-&darrow.
-&uarrow.
-&larrow.
-&rarrow.
-&rahead.
+-&mdash. +-&ndash. + &rbl. +!&xclm. +!&xclam. +"&cdq. +"&odq. +#&numsign. +$&dollar. +%&percent. +&&. +'&apos. +'&csq. +`&osq. +`&grave. +(&lpar. +(&lparen. +)&rpar. +)&rparen. +*&asterisk. +.&period. ++&plus. +,&comma. +-&dash. +-&emdash. +-&endash. +-&hyphen. +-&minus. +.&per. +/&slash. +/&slr. +:&colon. +;&semi. +>>. +>>sym. +=&eq. +=&equals. +=&eqsym. +<<. +<<sym. +@&atsign. +{&lbrace. +{&lbrc. +|&splitvbar. +|&vbar. +|&lor. +}&rbrace. +}&rbrc. +[&lbracket. +[&lbrk. +\&bslash. +\&bsl. +]&rbracket. +]&rbrk. +^&caret. +^&and. +_&us. +~&tilde. +~&similar. +&house. +&Cc. +&ue. +&ea. +&ac. +&ae. +&ag. +&ao. +&cc. +&ec. +&ee. +&eg. +&ie. +&ic. +&ig. +&Ae. +&Ao. +&angstrom. +&Ea. +æ. +Æ. +&oc. +&oe. +&og. +&uc. +&ug. +&ye. +&Oe. +&Ue. +¢. +&Lsterling. +¥. +&fnof. +&aa. +&ia. +&oa. +&ua. +&nt. +&Nt. +&aus. +&ous. +&invq. +&lnotrev. +&lnot. +¬sym. +½. +¼. +&inve. +&odqf. +&cdqf. +&alpha. +A&Alpha. +&Beta. +&Gamma. +&pi. +&Sigma. +&sigma. +&mu. +&tau. +&Phi. +&Theta. +&Omega. +&delta. +&infinity. +&phi. +&epsilon. +&intersect. +&identical. +&plusmin. +&pm. +&ge. +&gesym. +&le. +&lesym. +&inttop. +&intbot. +÷. +&nearly. +°ree. +°. +&bullet. +&dot. +&sqrt. +&supn. +². +&sqbul. +&box14. +&box12. +&box34. +&bx1012. +&bx2021. +&bx0021. +&bx0012. +&bx2022. +&bx2020. +&bx0022. +&bx2002. +&bx2001. +&bx1002. +&bx1210. +&bx2120. +&bx2200. +&bx0220. +&bx2202. +&bx0222. +&bx2220. +&bx0202. +&bx2222. +&bx1202. +&bx1201. +&bx0212. +&bx0121. +&bx2100. +&bx1200. +&bx0210. +&bx0120. +&bx2121. +&bx1212. +&bxas. +&bxbj. +&bxcr. +&bxcj. +&bxde. +&bxtj. +&bxh. +&bxll. +&bxlr. +&bxri. +&bxrj. +&bxul. +&bxur. +&bxv. +&BOX. +&BOXBOT. +&BOXLEFT. +&BOXRIGHT. +&BOXTOP. +&darrow. +&uarrow. +&larrow. +&rarrow. +&rahead. diff --git a/tools/wipfc/entit938.txt b/tools/wipfc/entit938.txt index 3f74faa0..7e6d05ab 100644 --- a/tools/wipfc/entit938.txt +++ b/tools/wipfc/entit938.txt @@ -1,202 +1,202 @@ --&mdash.
--&ndash.
- &rbl.
-!&xclm.
-!&xclam.
-"&cdq.
-"&odq.
-#&numsign.
-$&dollar.
-%&percent.
-&&.
-'&apos.
-'&csq.
-`&osq.
-`&grave.
-(&lpar.
-(&lparen.
-)&rpar.
-)&rparen.
-*&asterisk.
-.&period.
-+&plus.
-,&comma.
--&dash.
--&emdash.
--&endash.
--&hyphen.
--&minus.
-.&per.
-/&slash.
-/&slr.
-:&colon.
-;&semi.
->>.
->>sym.
-=&eq.
-=&equals.
-=&eqsym.
-<<.
-<<sym.
-@&atsign.
-{&lbrace.
-{&lbrc.
-|&splitvbar.
-|&vbar.
-|&lor.
-}&rbrace.
-}&rbrc.
-[&lbracket.
-[&lbrk.
-\&bslash.
-\&bsl.
-]&rbracket.
-]&rbrk.
-^&caret.
-^&and.
-_&us.
-~&tilde.
-~&similar.
- &house.
-&Cc.
- &ue.
- &ea.
- &ac.
- &ae.
- &ag.
- &ao.
- &cc.
- &ec.
- &ee.
- &eg.
- &ie.
- &ic.
- &ig.
- &Ae.
- &Ao.
- &angstrom.
- &Ea.
- æ.
- Æ.
- &oc.
- &oe.
- &og.
- &uc.
- &ug.
- &ye.
- &Oe.
- &Ue.
-¢.
-&sterlin.
-¥.
- &fnof.
- &aa.
- &ia.
- &oa.
- &ua.
- &nt.
- &Nt.
- &aus.
- &ous.
- &invq.
- &lnotrev.
- &lnot.
- ¬sym.
- ½.
- ¼.
- &inve.
-s&odqf.
-t&cdqf.
-&alpha.
-@&Alpha.
-B&Beta.
-&Gamma.
-&pi.
-&Sigma.
-&sigma.
-&mu.
-&tau.
-U&Phi.
-&Theta.
-&Omega.
-&delta.
-&infinity.
-&phi.
-&epsilon.
-&intersect.
-&indentical.
-}&plusmin.
-}&pm.
-&ge.
-&gesym.
-&le.
-&lesym.
- &inttop.
- &intbot.
-÷.
- &nearly.
-°ree.
-°.
-E&bullet.
-D&dot.
-&sqrt.
- &supn.
- ².
-&sqbul.
-&box14.
-&box12.
-&box34.
-&bx1012.
-&bx2021.
-&bx0021.
-&bx0012.
-&bx2022.
-&bx2020.
-&bx0022.
-&bx2002.
-&bx2001.
-&bx1002.
-&bx1210.
-&bx2120.
-&bx2200.
-&bx0220.
-&bx2202.
-&bx0222.
-&bx2220.
-&bx0202.
-&bx2222.
-&bx1202.
-&bx1201.
-&bx0212.
-&bx0121.
-&bx2100.
-&bx1200.
-&bx0210.
-&bx0120.
-&bx2121.
-&bx1212.
-&bxas.
-&bxbj.
-&bxcr.
-&bxcj.
-&bxde.
-&bxtj.
-&bxh.
-&bxll.
-&bxlr.
-&bxri.
-&bxrj.
-&bxul.
-&bxur.
-&bxv.
-&BOX.
- &BOXBOT.
- &BOXLEFT.
- &BOXRIGHT.
- &BOXTOP.
-&darrow.
-&uarrow.
-&larrow.
-&rarrow.
->&rahead.
+-&mdash. +-&ndash. + &rbl. +!&xclm. +!&xclam. +"&cdq. +"&odq. +#&numsign. +$&dollar. +%&percent. +&&. +'&apos. +'&csq. +`&osq. +`&grave. +(&lpar. +(&lparen. +)&rpar. +)&rparen. +*&asterisk. +.&period. ++&plus. +,&comma. +-&dash. +-&emdash. +-&endash. +-&hyphen. +-&minus. +.&per. +/&slash. +/&slr. +:&colon. +;&semi. +>>. +>>sym. +=&eq. +=&equals. +=&eqsym. +<<. +<<sym. +@&atsign. +{&lbrace. +{&lbrc. +|&splitvbar. +|&vbar. +|&lor. +}&rbrace. +}&rbrc. +[&lbracket. +[&lbrk. +\&bslash. +\&bsl. +]&rbracket. +]&rbrk. +^&caret. +^&and. +_&us. +~&tilde. +~&similar. + &house. +&Cc. + &ue. + &ea. + &ac. + &ae. + &ag. + &ao. + &cc. + &ec. + &ee. + &eg. + &ie. + &ic. + &ig. + &Ae. + &Ao. + &angstrom. + &Ea. + æ. + Æ. + &oc. + &oe. + &og. + &uc. + &ug. + &ye. + &Oe. + &Ue. +¢. +&sterlin. +¥. + &fnof. + &aa. + &ia. + &oa. + &ua. + &nt. + &Nt. + &aus. + &ous. + &invq. + &lnotrev. + &lnot. + ¬sym. + ½. + ¼. + &inve. +s&odqf. +t&cdqf. +&alpha. +@&Alpha. +B&Beta. +&Gamma. +&pi. +&Sigma. +&sigma. +&mu. +&tau. +U&Phi. +&Theta. +&Omega. +&delta. +&infinity. +&phi. +&epsilon. +&intersect. +&indentical. +}&plusmin. +}&pm. +&ge. +&gesym. +&le. +&lesym. + &inttop. + &intbot. +÷. + &nearly. +°ree. +°. +E&bullet. +D&dot. +&sqrt. + &supn. + ². +&sqbul. +&box14. +&box12. +&box34. +&bx1012. +&bx2021. +&bx0021. +&bx0012. +&bx2022. +&bx2020. +&bx0022. +&bx2002. +&bx2001. +&bx1002. +&bx1210. +&bx2120. +&bx2200. +&bx0220. +&bx2202. +&bx0222. +&bx2220. +&bx0202. +&bx2222. +&bx1202. +&bx1201. +&bx0212. +&bx0121. +&bx2100. +&bx1200. +&bx0210. +&bx0120. +&bx2121. +&bx1212. +&bxas. +&bxbj. +&bxcr. +&bxcj. +&bxde. +&bxtj. +&bxh. +&bxll. +&bxlr. +&bxri. +&bxrj. +&bxul. +&bxur. +&bxv. +&BOX. + &BOXBOT. + &BOXLEFT. + &BOXRIGHT. + &BOXTOP. +&darrow. +&uarrow. +&larrow. +&rarrow. +>&rahead.
\ No newline at end of file diff --git a/tools/wipfc/entity.txt b/tools/wipfc/entity.txt index d38b7986..c061ec24 100644 --- a/tools/wipfc/entity.txt +++ b/tools/wipfc/entity.txt @@ -1,203 +1,203 @@ --&mdash.
--&ndash.
- &rbl.
-!&xclm.
-!&xclam.
-"&cdq.
-"&odq.
-#&numsign.
-$&dollar.
-%&percent.
-&&.
-'&apos.
-'&csq.
-`&osq.
-`&grave.
-(&lpar.
-(&lparen.
-)&rpar.
-)&rparen.
-*&asterisk.
-.&period.
-+&plus.
-,&comma.
--&dash.
--&emdash.
--&endash.
--&hyphen.
--&minus.
-.&per.
-/&slash.
-/&slr.
-:&colon.
-;&semi.
->>.
->>sym.
-=&eq.
-=&equals.
-=&eqsym.
-<<.
-<<sym.
-@&atsign.
-{&lbrace.
-{&lbrc.
-|&splitvbar.
-|&vbar.
-|&lor.
-}&rbrace.
-}&rbrc.
-[&lbracket.
-[&lbrk.
-\&bslash.
-\&bsl.
-]&rbracket.
-]&rbrk.
-^&caret.
-^&and.
-_&us.
-~&tilde.
-~&similar.
-&house.
-&Cc.
-&ue.
-&ea.
-&ac.
-&ae.
-&ag.
-&ao.
-&cc.
-&ec.
-&ee.
-&eg.
-&ie.
-&ic.
-&ig.
-&Ae.
-&Ao.
-&angstrom.
-&Ea.
-æ.
-Æ.
-&oc.
-&oe.
-&og.
-&uc.
-&ug.
-&ye.
-&Oe.
-&Ue.
-¢.
-&Lsterling.
-¥.
-&fnof.
-&aa.
-&ia.
-&oa.
-&ua.
-&nt.
-&Nt.
-&aus.
-&ous.
-&invq.
-&lnotrev.
-&lnot.
-¬sym.
-½.
-¼.
-&inve.
-&odqf.
-&cdqf.
-&alpha.
-A&Alpha.
-&Beta.
-&Gamma.
-&pi.
-&Sigma.
-&sigma.
-&mu.
-&tau.
-&Phi.
-&Theta.
-&Omega.
-&delta.
-&infinity.
-&phi.
-&epsilon.
-&intersect.
-&identical.
-&plusmin.
-&pm.
-&ge.
-&gesym.
-&le.
-&lesym.
-&inttop.
-&intbot.
-÷.
-&nearly.
-°ree.
-°.
-&bullet.
-&dot.
-&sqrt.
-&supn.
-².
-&sqbul.
-&box14.
-&box12.
-&box34.
-&bx1012.
-&bx2021.
-&bx0021.
-&bx0012.
-&bx2022.
-&bx2020.
-&bx0022.
-&bx2002.
-&bx2001.
-&bx1002.
-&bx1210.
-&bx2120.
-&bx2200.
-&bx0220.
-&bx2202.
-&bx0222.
-&bx2220.
-&bx0202.
-&bx2222.
-&bx1202.
-&bx1201.
-&bx0212.
-&bx0121.
-&bx2100.
-&bx1200.
-&bx0210.
-&bx0120.
-&bx2121.
-&bx1212.
-&bxas.
-&bxbj.
-&bxcr.
-&bxcj.
-&bxde.
-&bxtj.
-&bxh.
-&bxll.
-&bxle.
-&bxlj.
-&bxlr.
-&bxri.
-&bxrj.
-&bxul.
-&bxur.
-&bxv.
-&BOX.
-&BOXBOT.
-&BOXLEFT.
-&BOXRIGHT.
-&BOXTOP.
-&darrow.
-&uarrow.
-&larrow.
-&rarrow.
-&rahead.
+-&mdash. +-&ndash. + &rbl. +!&xclm. +!&xclam. +"&cdq. +"&odq. +#&numsign. +$&dollar. +%&percent. +&&. +'&apos. +'&csq. +`&osq. +`&grave. +(&lpar. +(&lparen. +)&rpar. +)&rparen. +*&asterisk. +.&period. ++&plus. +,&comma. +-&dash. +-&emdash. +-&endash. +-&hyphen. +-&minus. +.&per. +/&slash. +/&slr. +:&colon. +;&semi. +>>. +>>sym. +=&eq. +=&equals. +=&eqsym. +<<. +<<sym. +@&atsign. +{&lbrace. +{&lbrc. +|&splitvbar. +|&vbar. +|&lor. +}&rbrace. +}&rbrc. +[&lbracket. +[&lbrk. +\&bslash. +\&bsl. +]&rbracket. +]&rbrk. +^&caret. +^&and. +_&us. +~&tilde. +~&similar. +&house. +&Cc. +&ue. +&ea. +&ac. +&ae. +&ag. +&ao. +&cc. +&ec. +&ee. +&eg. +&ie. +&ic. +&ig. +&Ae. +&Ao. +&angstrom. +&Ea. +æ. +Æ. +&oc. +&oe. +&og. +&uc. +&ug. +&ye. +&Oe. +&Ue. +¢. +&Lsterling. +¥. +&fnof. +&aa. +&ia. +&oa. +&ua. +&nt. +&Nt. +&aus. +&ous. +&invq. +&lnotrev. +&lnot. +¬sym. +½. +¼. +&inve. +&odqf. +&cdqf. +&alpha. +A&Alpha. +&Beta. +&Gamma. +&pi. +&Sigma. +&sigma. +&mu. +&tau. +&Phi. +&Theta. +&Omega. +&delta. +&infinity. +&phi. +&epsilon. +&intersect. +&identical. +&plusmin. +&pm. +&ge. +&gesym. +&le. +&lesym. +&inttop. +&intbot. +÷. +&nearly. +°ree. +°. +&bullet. +&dot. +&sqrt. +&supn. +². +&sqbul. +&box14. +&box12. +&box34. +&bx1012. +&bx2021. +&bx0021. +&bx0012. +&bx2022. +&bx2020. +&bx0022. +&bx2002. +&bx2001. +&bx1002. +&bx1210. +&bx2120. +&bx2200. +&bx0220. +&bx2202. +&bx0222. +&bx2220. +&bx0202. +&bx2222. +&bx1202. +&bx1201. +&bx0212. +&bx0121. +&bx2100. +&bx1200. +&bx0210. +&bx0120. +&bx2121. +&bx1212. +&bxas. +&bxbj. +&bxcr. +&bxcj. +&bxde. +&bxtj. +&bxh. +&bxll. +&bxle. +&bxlj. +&bxlr. +&bxri. +&bxrj. +&bxul. +&bxur. +&bxv. +&BOX. +&BOXBOT. +&BOXLEFT. +&BOXRIGHT. +&BOXTOP. +&darrow. +&uarrow. +&larrow. +&rarrow. +&rahead. |