Custom Layouts
What are custom layouts?
While this program was originally designed around my own preferences, I understand that everyone does things differently, and wanted to ensure that the editor would be able to adapt to fit anybody's work flow. In order to make this happen, version 0.13 added the ability to alter the locations and types of controls on the main window. These new arrangements are "custom layouts".
To help give you an idea of what these are capable of, several example layouts are provided along with Mike's Sprite Editor - you'll find them in the directory labeled "layouts". You're free to use them as they are or edit them to suit your preferences, but you can also create your own layouts from scratch using any plain text editor, such as Notepad.
How to make your own layouts
The layout files used by Mike's Sprite Editor are INI files. This is a well known and commonplace, if somewhat archaic, way of storing a program's data in a human readable format. In fact, the rules governing the structure of an INI file are simpler than the rules governing more modern solutions, like HTML, XML, or JSON. This ease of use, plus the fact that the editor already uses the INI format for storing your preferences, was why the INI format was selected for layouts.
Understanding INI file structure
INI files are plain text files that follow a few simple rules. The most basic rule is that each line of an INI file is its own "token", or instruction. Next, there are four types of instructions: comments, section headers, name/value pairs, and blank lines.
- Comments exist to provide additional information to anybody who's reading or editing the INI file. When software, such as Mike's Sprite Editor, sees a comment, it assumes the rest of the line is for humans and dutifully ignores everything on that line. To indicate a comment, the first non-whitespace character on a line must be a # (aka a pound sign or hashtag).
- Section headers mark the beginning of a section. Sections allow an INI file to contain multiple types of information, and the software will know what each section represents. Once a section header is seen, all of the name/value pairs that follow are assumed to be from that specific section. A section header is indicated by enclosing the section's name in square brackets [ ]. The only restrictions applied to section names is that they must all be unique, otherwise programs may inadvertently merge sections together and overwrite their name/value pairs.
- Name/value pairs store the actual information the file contains. These consist of a name, followed by an equal sign =, then the value. Traditionally, names or values containing spaces are to be enclosed in double quotes. The only thing to be mindful of here is that if two name/value pairs within a section share the same name, the second pair will overwrite the first. There can be as many spaces or tabs between the name or value and the = sign as you want; trailing or leading whitespace will be ignored.
- Lastly, blank lines (or lines containing only tabs and spaces) are just ignored and only function as decoration elements that make the file easier for a human to read.
To put this all together, here is an example of what a small INI file would look like:
[Entry 1] name = Jenny phone = 867-5309 [Entry 2] name = "Dr. Spengler" phone = 555-2368
Nice and simple, isn't it?
The main trick with INI files is knowing what sections, names, and values your software is expecting. The next section will explain how Mike's Sprite Editor turns these INI files into a layout.
Creating custom layouts
Without getting too technical, layouts are arrangements of different widgets, and layout files are INI files explaining which widgets go where. In a layout file, each section represents a different widget, and the name/value pairs in that section tell the editor about that specific widget.
In order to create and position a widget, the editor needs to know its type and position. Everything else is optional and will be filled in with default values if they aren't provided. Thus, adding a widget to your layout takes a minimum of four lines - the section header and three name/value pairs. Additional information, such as the widget's width or background color, may also be added, though some name/value pairs will have no effect on certain widgets.
One last thing before we get to the table of possible values: when it comes to layouts, the section names are not important - they just need to be unique. Lastly, the editor will add the widgets in the order they are listed. So, if any widgets overlap, the first one listed will be placed underneath its sibling. It's generally a bad idea to allow them to overlap though, so try to avoid it.
List of usable name/value pairs
Name | Acceptable Values | Usage and Meaning |
type |
ColorToggle Dimensions DrawingArea FillMode Generic Modified MousePosition PaletteBar Pattern ShapeSelect Toolbar TransBtn TransMode ZoomAmount |
This value determines what sort of widget is being described. Generic widgets do nothing, but can be used to create decorations on the editor's window. An example of this is seen in the default layout, where a generic widget is used to create the line separating the status bar area from the rest of the window. This name/value pair is required for every widget |
left | Any number |
This value represents the horizontal location, in pixels, of the widget's upper left corner. It may be negative. A horizontal position must be provided for each widget |
top | Any number |
This value represents the vertical location, in pixels, of the widget's upper left corner. It may be negative. A vertical position must be provided for each widget |
right | Any number |
This value represents the horizontal location, in pixels, of the widget's upper left corner, relative to the right side of the editor's window. It may be negative. A horizontal position must be provided for each widget |
bottom | Any number |
This value represents the vertical location, in pixels, of the widget's upper left corner, relative to the bottom of the editor's window. It may be negative. A vertical position must be provided for each widget |
width | Any number | This value represents the widget's width. If this number is negative, it is assumed to be an offset from the window's right edge. If this value is zero or was not provided, it's assumed that the widget's right side is against the window's right edge. |
height | Any number | This value represents the widget's height. If this number is negative, it is assumed to be an offset from the window's bottom edge. If this value is zero or was not provided, it's assumed that the widget's bottom side is against the window's bottom edge. |
buttons |
Copy Curve Cut EyeDropper Fill FlipHorz FlipVert Grid Line New Open Paste PasteFrom Pencil Replace Redo Revert RotClock RotCounter Save SaveAs Select Shape Spray Stamp Undo ZoomIn ZoomOut |
This field lists the buttons that are to appear on a Toolbar. You can list as many buttons as you want, separating them with any combination of spaces or commas. |
border | Any number | This places a border around the widget - a trick that may be useful while you're refining where everything goes, but may not look too good when the layout is finished. |
bordercolor | RRGGBB color value | This allows you to set the color of a widget's border. The border's size must also be defined in order for this to have any affect. |
textcolor | RRGGBB color value | This allows you to set the color of the widget's text. Note that most widgets do not have text, and will not respond to this option. |
windowcolor | RRGGBB color value | This allows you to change the background color of most widgets. Some widgets, such as DrawingArea widgets, don't use a plain fill for their background, and thus they won't respond to this option. |
main | TRUE or FALSE |
If there is more than one DrawingArea, you should define which one should be treated as the "main" DrawingArea, as some of the editor's features will base their actions on this DrawingArea's status. If no DrawingArea is defined as the main one, the editor will simply consider the first DrawingArea in the layout as the main one. This is not needed when there is only one DrawingArea widget. |