Skinning Checkbox with Error State
Similar to skinning a combobox with an error state, there may be times where you need to show the error state for a checkbox without showing its error string.
main.css
CheckBox { icon : ClassReference("com.lejnieks.poc.ui.skins.CheckboxBorderSkin"); error-color : #FF0000; fillColors : #fdfdfd, #e2e3e3, #e6f5ff, #e6f5ff; borderColor : #374149; outerBorderColor : #77848D; themeColor : #77848d; icon-color : #2A2A2A; disabled-icon-color : #7A7A7A; color : #DEEEF9; textSelectedColor : #DEEEF9; textRollOverColor : #DEEEF9; fontFamily : Tahoma; fontSize : 10; fontWeight : normal; }
CheckboxBorderSkin.as
package com.lejnieks.poc.ui.skins { import com.lejnieks.poc.ui.controls.IValidatable; import mx.controls.CheckBox; import mx.skins.halo.CheckBoxIcon; public class CheckboxBorderSkin extends CheckBoxIcon implements IValidatable { private var _showError:Boolean = false; public function get showError():Boolean { return _showError; } public function set showError(value:Boolean):void { _showError = value; invalidateProperties(); } override protected function updateDisplayList(w:Number, h:Number):void { super.updateDisplayList(w, h); var bDrawCheck:Boolean = false; var fillAlphas:Array = [1, 1]; var highlightAlphas:Array = [1, 1]; var checkColor:uint = getStyle("iconColor"); var borderColor:uint = getStyle("borderColor"); var outerBorderColor:uint = getStyle("outerBorderColor"); var fillColors:Array = getStyle("fillColors"); var isErrorState:Boolean = false; if( !_showError ) { if(parent is CheckBox && CheckBox(parent).errorString.length > 1 && CheckBox(parent).errorString != "" && CheckBox(parent).errorString != null ) { isErrorState = true; } } graphics.clear(); switch( name ) { case "upIcon": if(isErrorState || _showError) { drawRoundRect( -1, -1, w + 2, h + 2, 0, outerBorderColor, 1 ); } drawRoundRect( 0, 0, w, h, 0, borderColor, 1 ); drawRoundRect( 1, 1, w - 2, h - 2, 0, [ fillColors[0], fillColors[1] ], 1, verticalGradientMatrix(1, 1, w - 2, h - 2) ); break; case "overIcon": drawRoundRect( -1, -1, w + 2, h + 2, 0, outerBorderColor, 1 ); drawRoundRect( 0, 0, w, h, 0, borderColor, 1 ); drawRoundRect( 1, 1, w - 2, h - 2, 0, [ fillColors[0], fillColors[1] ], 1, verticalGradientMatrix(1, 1, w - 2, h - 2) ); case "downIcon": drawRoundRect( -1, -1, w + 2, h + 2, 0, outerBorderColor, 1 ); drawRoundRect( 0, 0, w, h, 0, borderColor, 1); drawRoundRect( 1, 1, w - 2, h - 2, 0, [ fillColors[2], fillColors[3] ], 1, verticalGradientMatrix(1, 1, w - 2, h - 2) ); break; case "disabledIcon": drawRoundRect( 0, 0, w, h, 0, borderColor, 0.5); drawRoundRect( 1, 1, w - 2, h - 2, 0, [ fillColors[0], fillColors[1] ], [0.5, 0.5], verticalGradientMatrix(1, 1, w - 2, h - 2) ); break; case "selectedUpIcon": bDrawCheck = true; if(isErrorState || _showError) { drawRoundRect( -1, -1, w + 2, h + 2, 0, outerBorderColor, 1 ); } drawRoundRect( 0, 0, w, h, 0, borderColor, 1); drawRoundRect( 1, 1, w - 2, h - 2, 0, [ fillColors[0], fillColors[1] ], 1, verticalGradientMatrix(1, 1, w - 2, h - 2) ); break; case "selectedOverIcon": bDrawCheck = true; drawRoundRect( -1, -1, w + 2, h + 2, 0, outerBorderColor, 1 ); drawRoundRect( 0, 0, w, h, 0, borderColor, 1); drawRoundRect( 1, 1, w - 2, h - 2, 0, [ fillColors[0], fillColors[1] ], 1, verticalGradientMatrix(1, 1, w - 2, h - 2) ); case "selectedDownIcon": bDrawCheck = true; drawRoundRect( -1, -1, w + 2, h + 2, 0, outerBorderColor, 1 ); drawRoundRect( 0, 0, w, h, 0, borderColor, 1 ); drawRoundRect( 1, 1, w - 2, h - 2, 0, [ fillColors[2], fillColors[3] ], 1, verticalGradientMatrix(1, 1, w - 2, h - 2) ); break; case "selectedDisabledIcon": bDrawCheck = true; checkColor = getStyle("disabledIconColor"); drawRoundRect( 0, 0, w, h, 0, borderColor, 0.5); drawRoundRect( 1, 1, w - 2, h - 2, 0, [ fillColors[0], fillColors[1] ], [0.5, 0.5], verticalGradientMatrix(1, 1, w - 2, h - 2) ); break; } if (bDrawCheck) { graphics.beginFill(checkColor); graphics.moveTo(3, 5); graphics.lineTo(5, 10); graphics.lineTo(7, 10); graphics.lineTo(12, 2); graphics.lineTo(13, 1); graphics.lineTo(11, 1); graphics.lineTo(6.5, 7); graphics.lineTo(5, 5); graphics.lineTo(3, 5); graphics.endFill(); } } } }
IValidatable.as
package com.lejnieks.poc.ui.controls { /** * The interface that components implement to * support validation of fields. This component * bypasses the need to use Validators. * Custom ui components implement this interface * therefore all custom ui component in the application can be * iterated through during a validation process * and set to show its error state or clear its error state. */ public interface IValidatable { /** * Every <cod>IValidatable</code> component will have a proper error * skin. Setting <code>showError</code> to true will invoke this setter * and flag the component to display the error skin on the next * <cod>commitPropeties</code>. * * <p>Calling <code>showError</code> is similar to setting <code>errorString</code> * except that some components may not need to display an error string but still show * its error skin.</p> * <p>IValidatable components in the application can display error skins regardless of setting an * errorString. This is important to note for child components whose parent containers * will set or show an error string or who wont show an error message at all but simply * display a skin or icon for its errored state</p> * */ function get showError():Boolean; function set showError(value:Boolean):void; } }