070606 - Added a new field, currentSelection (of type java.awt.geom.Rectangle2D) to the BrushManager class to track the bounding rect of the bristles currently selected in the Bristles list. Prior, when using the rotation field in the status bar located in the BrushDesigner, it was using successive iterations of the "current" bounding rect (which would change each time individual bristles were rotated), thereby producing incorrect results. - Removed getSelectionCenter()/setSelectionCenter() methods from the BrushDesigner class, as well as the selectionCenter (of type java.awt.geom.Point2D). They were not being utilized for anything, and if needed, this value can be derived from the currentSelection (see above). - Added a new Listener and Event type - BrushDesignerStateChangeListener, and BrushDesignerStateChangeEvent. The purpose of these lies in being able to listen for modifications to the state of objects, such as scaling, rotating, moving, etc. - Added stateChangeListenerList field (type Vector), and addStateChangeListener(), removeStateChangeListener, and fireStateChangeEvent() methods to core/BrushDesigner.java. - Modified the code in core/Semicuro.java so that the BrushManager class is registered with BrushDesigner as a BrushDesignerStateChangeListener. 070706 - Added a brushDesignerStateChanged() method to core/BrushManager.java to respond to BrushDesignerStateChange events. This response updates the currentBounds field with the new bounding rectangle associated with the selected bristles. - Modified the modifyStatus method in core/BrushManager to correct the method of calculation when the selected bristles were modified by manually entering values into the w and h fields in the Brush Designer status bar. 071606 - Added code to trap out-of-memory conditions, so that the user is informed when this happens. - Refined the handling of null pointer conditions (which occur when memory cannot be allocated (for a request to create a new image, for example). Users will now see a dialog warning of any out-of-memory conditions related to the creation of new images. - Added a field to the Bristle class to contain a reference to its parent Brush, as well as the code to populate that reference when a new bristle is created. - Added a field to the BristleModel to contain a reference to a Shape that will serve as the target for a new (yet to be implemented) "Follow path" feature. The intent is to have this shape define a series of points at which the bristle will be rendered. 071706 - Fixed a bug related to the Threshold setting under the Alpha tab- it wasn't being udpated correctly when switching between bristles. - New feature - when holding the CTRL key down while rotating a bristle in the Brush Designer, it will rotate the selected bristles around their respective anchor points, rather than the center of the bounding rectangle. 072907 - Fixed a bug that caused the brush files in the users ._semicuro_ directory on a Windows machine to be rendered unusable when a file modification process was run at startup right after a new version of the software was installed. 081307 - Eliminated the dialog that appears (repeatedly) on startup when non-XML files are encountered while loading any brushes that may exist in the user's ._semicuro_ directory. Now these files are simply ignored. If they are .temp files on a Windows machine, these will be cleared out the next time the workspace is saved. 090706 - Fixed a bug that caused the PaintWrap option to produce wrapped images that were off by one pixel. If the wrap occurred along the x axis, the wrapped portion of the image would appear one pixel off along the y axis. If the wrap occurred along the y axis, the wrapped portion of the image would appear one pixel off along the x axis. 122006 - Ran into a problem with ImageIcon recognizing and handling jpg images, so the only jpg image that was currently being used (imagenotfound.jpg), was converted to a png format. This seems to have solved the problem, which manifested itself as a sudden halt during loading (due to a NullPointerException) when the app encountered a bristle with an image file that did not exist at the specified location. 010107 - Added rudimentary support for preferences, via the semicuro.config file. The configuration directory has been changed from ~/._semicuro_ to ~/.semicuro. This new configuration location will contain two items: the a directory for brushes (the user's workspace), and a new configuration file, semicuro.config. Any brushes that exist in the old location (~/._semicuro_) will be copied to the new location the first time 1.0 is loaded. The new preferences file contains two property so far: lookandfeel and paintcursor. The "default" value for lookandfeel can changed to the fully-qualified class name of any LookAndFeel that has been included with the build. There is one LookAndFeel available at this point: com.lipstikLF.LipstikLookAndFeel However, this LookAndFeel currently has issues with menu items that have icons. There are also some minor issues with object placement (the components that make up the various panels in the PaintManager). org.semicuro.core.Semicuro.java underwent some additions to handle this new functionality. The default value for paintcursor can be changed to "crosshair" if you need more precision while painting. - The build file (build.xml) was modified to handle the process in a more flexible manner. You can now initiate the build process by typing "ant" without having to specify which platform - it will make that determination on its own. The result of the build process will be a "build" directory populated with the appropriate files, as well as compressed archive (zip for windows, tgz for linux) in a "dist" directory. Producing a source archive still requires using "ant src_dist". 010607 - Added a new Preview function to the canvas window (org.semicuro.core.SCCanvas). To faciliate this, a new interface was created (org.semicuro.ui.Preview.java), and an implementation (org.semicuro.ui.TileablePreview.java). When this button is activated, it opens a window containing a 3 x 3 matrix of tiled images. The preview is automatically updated each time the mouse is released, or when the image is altered using any of the filters/dialogs, etc. - Moved the non-static getCompositeImage() methods from the org.semicuro.ui.LayerManager class to a new, more specialized class (org.semicuro.core.ImageUtils) as static methods. This was done to facilitate greater clarity and more flexible access. Other image-related utility functions that currently reside in the Utils class should also be relocated to this ImageUtils class at some point in order to maintain semantic consistency. - Added accessor methods to the org.semicuro.ui.CanvasTools class for each of the buttons that appear in the toolbar, allowing the addition of listeners to these components if needed. The construction of an SCCanvas now includes adding a listener to the toolbar's Preview button. 012807 - Completely reworked the Paint Wrap code, eliminating the ImageReflector class. The rewrite allowed the elimination of two bugs: one which prevented wrapping strokes to a diagonally oposite corner, and another which failed to include any scale settings in the wrapped portion of a stroke. 013007 - Changed the manner in which the application is initialized. Instead of creating a new instance using the new() method, the Semicuro class has been turned into a singleton. Creating a new instance now requires a call to Semicuro.getInstance(). This was done to accommodate access to the configuration properties, which are stored as name/value pairs in the semicuro.config file. - Added a new configuration property called 'paintcursor'. This property is used to specify a crosshair cursor instead of the default sprayer cursor that is visible while painting in the texture window.