Wednesday, August 19, 2009

Version 0.98 (http://www.sparseware.com/sage/demos/) is out. I have been busy working on a real world sage application with real requirements in order to help flesh out the sage feature set and smooth out the rough edges. I finally came to a good stopping point and can now put out a new version. There are a couple of significant new features and a couple of nice to haves. The old demos’ have been upgraded to look better/cleaner and to take advantage of some of the new features and a new demo(Black Majic) has been created to show of the flasher side of Sage. Some of the things featured in the new demo are:
  • a shaped windows using soft clipping, achieved by setting the opaque attribute to false and using a shaped border,
  • skinning via dynamic color management and combox, slider, and scrollbar customization,
  • window translucency (Disappearing act slider) ,
  • support for plugin animations (see the load animation of the Skynard panel) ,
  • and last but not least JavaFX integration via a JavaFX scene viewer for Sage

Text/Icon Zooming

Sage now supports text and icon zooming similar to what is found in most other browsers.
Simply call the setRelativeFontSize method on the sage object with a value other than 1 and the application will be zoomed accordingly.
The following JavaScript function zooms in by 10% (relative to the normal size) every time the function is called:
function increaseFontSize() {
var rsize=sage.relativeFontSize
rsize+=.1
if(rsize>3) {
window.beep()
}
else {
sage.relativeFontSize=rsize
}
}
One of the problems with scaling no-vector based graphics is that you loose fidelity as you scale up. Most of the time scaling a big image down by 50% produces an image that is better looking than scaling a small image up by 100%. Whether or not you want sage to automatically scale icons during zooming is controlled via the scaleIconsWithFont property on the application configuration object. It is defined as follows:
scaleIconsWithFont Boolean Default false [defaultBaseSize, defaultBaseScaleFactor, scaling="bilinear_cached"]
The defaultBaseSize and defaultBaseScaleFactor attributes lets you determine the default size for your icons and the default scaling base for those icons when the relative font size is equal to 1. This allows you to use icons that are larger than the standard 16x16 and have sage scale them down to 16x16. For example, the following configuration will automatically scale all 24x24 images (that don't explicitly have a scaling base defined) down to 16x16 images when the relative font size is equal to 1.
scaleIconsWithFont: true [defaultBaseScaleFactor="0.666666666", defaultBaseSize="24x24"]
The images will be scaled using bilinear interpolation and the resulting value cached (default value for the scaling attribute).
This functionality can be seen in the Outlook demo using the view menu zooming options or pressing Ctrl+Plus to zoom in and
Ctrl+Minus to zoom out. The outlook demo was redesigned to use font sensitive units for layout, component preferred sizes, and table column widths. Sage will automatically layout and resize widgets and columns (if they haven't been resized by the user), as appropriate, when the relative font size changes. The icons in the demo are all 16x16. I was too lazy to create higher fidelity ones.

Scriptable HTML Forms

HTML forms are now supported by the document pane.
Sage widgets are created for form elements, allowing them to be skinned, scripted, and controlled like any other Sage widget.
Also supported is a custom input type and the ability to use the class attribute to configure sage properties. For example if you wanted to have a radio button where the text was part of the button you could use the following HTML:
<input type="radio" name="rb_1" value="hello" class="RadioButton{value='Hello World'}">
In a regular browser you would just get the button with no text. In sage you would get a button with the text "Hello World" next to it and the user will be able to click on the text to toggle the button.

To insert a real table widget (not an HTML table) you could do the following:
<input type="custom" name="table_1" class="Table{templateName: 'mytable_template' }">
This would create a table using the information contained in the 'mytable_template' template to configure the table. You could put the complete table definition in the class attribute but that would be a very long line and look a little sloppy (which doesn't matter if the HTML is being programmatically generated).

Dynamic Color Management

Sage now allows you to dynamically update the color of all widgets/painters by simply changing the value of a named color. Activating this support is simply a matter of setting the keep_color_keys attribute on the lookAndFeelPropertiesURL property of the application to true. The following definition derives all colors that are part of a color scheme from a single color:
lookAndFeelPropertiesURL:<<
defaultBackground=MappedColor|#EDE9E3 [os="windows,linux"]
defaultBackground=MappedColor|#E8E8E8 [os="os x"]
tableGrid=MappedColor|defaultBackground@50
tableAlternating=MappedColor|defaultBackground@25
menuBackground=MappedColor|defaultBackground+25

Sage.controlLtGradient=Color|defaultBackground+5
Sage.controlDkGradient=Color|defaultBackground-5
Sage.control=Color|defaultBackground
Sage.controlShadow=Color|defaultBackground-25
Sage.controlDkShadow=Color|defaultBackground-50
Sage.controlLtShadow=Color|defaultBackground-5
Sage.controlHighlight=Color|defaultBackground-5
Sage.controlLtHighlight=Color|white

Sage.ScrollBar.thumb=Color|defaultBackground-5 [os="windows,linux"]
Sage.ScrollBar.thumbShadow=Color|Sage.controlShadow [os="windows,linux"]
Sage.ScrollBar.thumbDarkShadow=Color|Sage.controlDkShadow [os="windows,linux"]
Sage.ScrollBar.arrow=Color|Sage.controlDkShadow [os="windows,linux"]
Sage.ScrollBar.background=Color|defaultBackground-5 [os="windows,linux"]
Sage.ScrollBar.shadow=Color|Sage.controlShadow [os="windows,linux"]
Sage.ScrollBar.trackBorder=Color|Sage.controlDkShadow [os="windows,linux"]

Sage.ComboBox.border=Border|{line_3d [cornerArc="6",padForArc=false]}
Sage.ComboBox.background=BackgroundColor|white|defaultBackground-5 [os="windows,linux"]
PopupMenu.background=Color|menuBackground
PopupMenuSeparator.background=Color|menuBackground
Menu.mouseHoverBorder=Border|{line}
Menu.mouseHoverBackground=Color|menuBackground
Menu.selectionBackground=Color|menuBackground
Menu.background=Color|menuBackground
Menu.selectionBorderColor=Color|Sage.controlShadow
MenuItem.background=Color|menuBackground
MenuItem.selectionBorderColor=Color|Sage.controlShadow
MenuItem.shadowColor==Color|defaultBackground+5
CheckBoxMenuItem.background=Color|menuBackground
CheckBoxMenuItem.selectionBorderColor=Color|Sage.controlShadow
>> [ inline="true", keep_color_keys=true]
The BackgroundColor class designates the color is a background color (which means that it can be a gradient). The MappedColor class designates that colors derived form this color will all reference the named and not reference the actual color value.
Note: color@50 gives you a 50% transparency; color-50 gives you a color with 50% less luminance; [os="windows,linux"] means that these values should only be used for windows and Linux

The configuration produces the following color scheme (on windows and Linux, the scheme is gray for OS X)

Executing the following JavaScript code:
sage.UIDefaults["defaultBackground"]= window.getColor("#DCE0DC")
window.update()
Will instantly make the application look like this:

Other Niceties

  • Shaped and translucent windows are supported for JRE 1.6u10 and later, or if the JNA library is in the class path. The windowPainter property of the MainWindow objects allows you to specify a background image, background color/gradient and border for the main window (the border is placed on the root pane). The contentPanePainter property allows you to specify a background image, background color/gradient and border for the content pane. If you set true useBorderShape to true then the window will be shaped to match the specified border and sage will handle the reshaping when the windows is resized or maximized
  • Support for load and transition animations and other custom effects via the print primer/finisher interface that allows complete control over paint surfaces.
  • Improved slider, scrollbar and combo box skinning
  • Ruby is now a first class scripting language