LogoLogo
  • Home
  • Projects
  • About
  • Contact

“FontBox” – ComboBox for Font Selection

Devon O. · March 02, 2008 · Actionscript, Flash · 0 comments
3

Many moons ago someone over at the Kirupa forum asked how to create a combo box that could display a list of fonts in their “natural state”. Sounded pretty interesting so I whipped together a quick example that made use of some graphics in the .fla library. It was nice and worked, but I thought I’d revisit this idea and rework it so no custom graphics were necessary. Unfortunately, it still requires fonts to be included in the .fla library which, of course, jacks up the file size, but that can’t really be avoided. The final result is here:

the graphics class

C#
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package com.onebyonedesign.ui.graphics {    
 
    import flash.display.CapsStyle;
    import flash.display.LineScaleMode;
    import flash.display.SimpleButton;
    import flash.display.Sprite;    
 
    /**
    * Creates graphic display for UI combo box
    * @author Devon O.
    * @date 3/2/2008 8:50 AM
    */
    public class ComboBoxGraphic extends Sprite {    
 
        private var _w:int;
        private var _h:int;
        private var _button:SimpleButton;
        private var _arrow:Sprite;    
 
        public function ComboBoxGraphic(width:int, height:int):void {
            _w = width;
            _h = height;    
 
            drawBox();
            addButton();
            addArrow();
        }    
 
        private function drawBox():void {
            graphics.lineStyle(1, 0x848484, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            graphics.moveTo(0, _h - 1);
            graphics.lineTo(0, 0);
            graphics.lineTo(_w, 0);
            graphics.lineStyle(1, 0xE3DDDD, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            graphics.moveTo(_w, 1);
            graphics.lineTo(_w, _h - 1);
            graphics.lineStyle(1, 0xE9E9E9, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            graphics.moveTo(_w, _h);
            graphics.lineTo(0, _h);
            graphics.lineStyle(1, 0xE3DDDD, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            graphics.moveTo(1, 1);
            graphics.lineTo(_w - 1, 1);
            graphics.lineTo(_w - 1, _h - 1);
            graphics.lineTo(1, _h - 1);
            graphics.lineTo(1, 1);
            cacheAsBitmap = true;
        }    
 
        private function addButton():void {
            var btnSize:int = _h - 4;    
 
            var upstate:Sprite = new Sprite();
            upstate.graphics.beginFill(0xFFFFFF);
            upstate.graphics.lineStyle(1, 0xE3DDDD, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            upstate.graphics.moveTo(0, 0);
            upstate.graphics.lineTo(btnSize - 1, 0);
            upstate.graphics.lineTo(btnSize - 1, btnSize - 1);
            upstate.graphics.lineTo(0, btnSize - 1);
            upstate.graphics.lineTo(0, 0);
            upstate.graphics.endFill();
            // shadow
            upstate.graphics.lineStyle(1, 0x848484, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            upstate.graphics.moveTo(0, btnSize);
            upstate.graphics.lineTo(btnSize, btnSize);
            upstate.graphics.lineTo(btnSize, 0);
            upstate.cacheAsBitmap = true;    
 
            var overstate:Sprite = new Sprite();
            overstate.graphics.beginFill(0xF5F5F5);
            overstate.graphics.lineStyle(1, 0xE3DDDD, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            overstate.graphics.moveTo(0, 0);
            overstate.graphics.lineTo(btnSize - 1, 0);
            overstate.graphics.lineTo(btnSize - 1, btnSize - 1);
            overstate.graphics.lineTo(0, btnSize - 1);
            overstate.graphics.lineTo(0, 0);
            overstate.graphics.endFill();
            // shadow
            overstate.graphics.lineStyle(1, 0x848484, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            overstate.graphics.moveTo(0, btnSize);
            overstate.graphics.lineTo(btnSize, btnSize);
            overstate.graphics.lineTo(btnSize, 0);
            overstate.cacheAsBitmap = true;    
 
            var downstate:Sprite = new Sprite();
            downstate.graphics.beginFill(0xF5F5F5);
            downstate.graphics.lineStyle(1, 0x848484, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            downstate.graphics.moveTo(0, btnSize - 1);
            downstate.graphics.lineTo(0, 0);
            downstate.graphics.lineTo(btnSize - 1, 0);
            downstate.graphics.lineStyle(1, 0xE3DDDD, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            downstate.graphics.lineTo(btnSize - 1, btnSize - 1);
            downstate.graphics.lineTo(0, btnSize - 1);
            downstate.graphics.endFill();
            // shadow
            downstate.graphics.lineStyle(1, 0xE3DDDD, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE);
            downstate.graphics.moveTo(0, btnSize);
            downstate.graphics.lineTo(btnSize, btnSize);
            downstate.graphics.lineTo(btnSize, 0);
            downstate.cacheAsBitmap = true;    
 
            var hitstate:Sprite = new Sprite();
            hitstate.graphics.beginFill(0x000000);
            hitstate.graphics.moveTo((btnSize + 1) - _w, -2);
            hitstate.graphics.lineTo(btnSize + 1, -2);
            hitstate.graphics.lineTo(btnSize + 1, btnSize + 2);
            hitstate.graphics.lineTo((btnSize + 1) - _w, btnSize + 2);
            hitstate.graphics.endFill();
            hitstate.cacheAsBitmap = true;    
 
            _button = new SimpleButton(upstate, overstate, downstate, hitstate);    
 
            _button.x = _w - btnSize - 1;
            _button.y = 2;
            addChild(_button);
        }    
 
        private function addArrow():void {
            _arrow = new Sprite();
            _arrow.graphics.beginFill(0x282828);
            _arrow.graphics.moveTo(0, 0);
            _arrow.graphics.lineTo(6, 0);
            _arrow.graphics.lineTo(3, 3);
            _arrow.graphics.lineTo(0, 0);
            _arrow.graphics.endFill();
            _arrow.cacheAsBitmap = true;    
 
            _arrow.x = int((_button.x + (_button.width / 2)) - (_arrow.width / 2));
            _arrow.y = int((_h / 2) - (_arrow.height / 2));
            addChild(_arrow);
        }
    }
}

The event class:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.onebyonedesign.ui.events {    
 
    import flash.events.Event;    
 
    public class FontBoxEvent extends Event {    
 
        public static const FONT_SELECTED:String = "onFontSelected";    
 
        public function FontBoxEvent(type:String):void {
            super(type);
        }
    }
}

The “main” class:

C#
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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
package com.onebyonedesign.ui {    
 
    import com.onebyonedesign.ui.events.FontBoxEvent;
    import com.onebyonedesign.ui.graphics.ComboBoxGraphic;
    import flash.display.MovieClip;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.AntiAliasType;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.text.Font;    
 
    /**
    * Creates combo box that displays font styles in their natural format
    * @author Devon O.
    * @date 3/2/2008 8:50 AM
    */    
 
    public dynamic class FontBox extends MovieClip {    
 
        private var _title:String;
        private var _initialText:String;
        private var _fontProvider:Array;
        private var _boxWidth:int;
        private var _boxHeight:int;
        private var _displayFontSize:int;
        private var _displayFont:String;
        private var _fontSize:int;    
 
        private var _titleText:TextField;
        private var _selectedText:TextField;    
 
        private var _comboBox:ComboBoxGraphic;    
 
        private var _choices:Array =  new Array();
        private var _choiceHolder:Sprite = new Sprite();;
        private var _font:Font;    
 
        /**
         * returns the selected font
         */
        public function get font():Font {
            return _font;
        }    
 
        /**
         *
         * @param    String that will be displayed as the title of the combobox instance
         * @param    String that will be initally displayed inside combobox
         * @param    array of Font instances that will be displayed
         * @param    width of combobox graphic
         * @param    height of combobox graphic
         * @param    String name of font used for title and text displayed inside combobox
         * @param    size of font displayed in title and inside combobox
         * @param    size of fonts displayed in drop down list
         */
        public function FontBox(title:String, initialDisplayText:String, fontList:Array, width:int = 120, height:int = 18, displayFont:String = "_sans", displayFontSize:int = 11, fontSize:int = 22):void {
            _title = title;
            _initialText = initialDisplayText;
            _fontProvider = fontList;
            _boxWidth = width;
            _boxHeight = height;
            _displayFont = displayFont;
            _displayFontSize = displayFontSize;
            _fontSize = fontSize;    
 
            init();
        }    
 
        private function init():void {
            createTitle();
            createBox();
        }    
 
        private function createTitle():void {
            _titleText = new TextField();
            _titleText.autoSize = TextFieldAutoSize.LEFT;
            _titleText.selectable = false;
            _titleText.defaultTextFormat = new TextFormat(_displayFont, _displayFontSize);
            _titleText.antiAliasType = AntiAliasType.ADVANCED;
            _titleText.text = _title;
            addChild(_titleText);
        }    
 
        private function createBox():void {
            _comboBox = new ComboBoxGraphic(_boxWidth, _boxHeight);
            _comboBox.x = int(_titleText.width + 10);
            addChild(_comboBox);    
 
            _selectedText = new TextField();
            _selectedText.width = _boxWidth - _boxHeight;
            _selectedText.selectable = false;
            _selectedText.mouseEnabled = false;
            _selectedText.defaultTextFormat = new TextFormat(_displayFont, _displayFontSize);
            _selectedText.antiAliasType = AntiAliasType.ADVANCED;
            _selectedText.text = _initialText;
            _selectedText.x = _comboBox.x + 1;
            addChild(_selectedText);    
 
            _comboBox.addEventListener(MouseEvent.CLICK, onClick);
        }    
 
        // Events
        private function onOut(me:MouseEvent):void {
            removeChoices();
            _choices = new Array();
        }    
 
        private function onClick(me:MouseEvent):void {
            parent.setChildIndex(this, parent.numChildren - 1);
            addChoices();
        }    
 
        private function onSelect(me:MouseEvent):void {
            _selectedText.text = me.target.label;
            _font = me.target.data;
            dispatchEvent(new FontBoxEvent(FontBoxEvent.FONT_SELECTED));
            removeChoices();
        }    
 
        private function addChoices():void {
            _choiceHolder.x = _comboBox.x;
            _choiceHolder.y = _comboBox.height;
            _fontProvider.forEach(addChoice);
            _choiceHolder.addEventListener(MouseEvent.ROLL_OUT, onOut);
            addChild(_choiceHolder);
        }    
 
        private function addChoice(f:Font, i:int, a:Array):void {
            var c:Choice = new Choice(f.fontName, f, _boxWidth, _fontSize);
            _choices.push(c);
            c.useHandCursor = false;
            if (i > 0)
                c.y = _choices[i - 1].y + _choices[i - 1].height;
            c.addEventListener(MouseEvent.CLICK, onSelect);
            _choiceHolder.addChild(c);
        }    
 
        private function removeChoices():void {
            if (contains(_choiceHolder)) removeChild(_choiceHolder);
        }
    }
}    
 
//    Choice class    
 
import flash.display.SimpleButton;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.AntiAliasType;
import flash.text.Font;
import flash.display.Sprite;    
 
class Choice extends SimpleButton {    
 
    private var _fontLabel:TextField;
    private var _size:int;
    private var _width:int;
    private var _label:String;
    private var _data:Font;
    private var _boxHeight:Number;    
 
    public function get label():String {
        return _label;
    }
    public function get data():Font {
        return _data;
    }    
 
    function Choice (label:String, data:Font, width:int, fontsize:int) {
        _label = label;
        _data = data;
        _size = fontsize;
        _width = width;
        _fontLabel = addLabel();
        _boxHeight = _fontLabel.height;
        upState = upSprite();
        overState = overSprite();
        downState = upSprite();
        hitTestState = upSprite();
    }
    private function upSprite():Sprite {
        var s:Sprite = new Sprite();
        s.graphics.beginFill(0xEFEFEF);
        s.graphics.drawRect(0, 0, _width, _boxHeight);
        s.graphics.endFill();
        s.addChild(addLabel());
        return s;
    }
    private function overSprite():Sprite {
        var s:Sprite = new Sprite();
        s.graphics.beginFill(0xDFDFDF);
        s.graphics.drawRect(0, 0, _width, _boxHeight);
        s.graphics.endFill();
        s.addChild(addLabel());
        return s;
    }    
 
    private function addLabel():TextField {
        var tf:TextField = new TextField();
        tf.antiAliasType = AntiAliasType.ADVANCED;
        var fmt:TextFormat = new TextFormat(_data.fontName, _size);
        tf.defaultTextFormat = fmt;
        tf.embedFonts = true;
        tf.selectable = false;
        tf.mouseEnabled = false;
        tf.text = _label;
        tf.width = _width - 2;
        tf.height = tf.textHeight;
        return tf;
    }
}

And finally a document class test:

C#
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
package {    
 
    import com.onebyonedesign.ui.events.FontBoxEvent;
    import com.onebyonedesign.ui.FontBox;
    import flash.display.Sprite;
    import flash.text.AntiAliasType;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;    
 
    public class Test extends Sprite {    
 
        private var _fontBox:FontBox;
        private var _lipsum:String = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas at leo eget nisl porta viverra. Ut laoreet, dui at tempus vestibulum, eros leo egestas neque, id adipiscing odio eros et lectus. Vivamus pretium lorem sit amet nulla. Praesent nec dolor at augue ultrices blandit."
        private var _exampleText:TextField;
        private var _format:TextFormat = new TextFormat(new ArialFont().fontName, 12);    
 
        public function Test():void {
            initExampleText();
            initFontBox();
        }    
 
        private function initFontBox():void {    
 
            //    ArialFont, ComicFont, CourierFont and TimesFont are fonts included in .fla library    
 
            var fontArray:Array = new Array(new ArialFont(), new ComicFont(), new CourierFont(), new TimesFont());
            _fontBox = new FontBox("Fonts:", "-choose a font-", fontArray, 150);
            _fontBox.x = 50;
            _fontBox.y = 50;
            _fontBox.addEventListener(FontBoxEvent.FONT_SELECTED, onFontSelect);
            addChild(_fontBox);
        }    
 
        private function initExampleText():void {
            _exampleText = new TextField();
            _exampleText.multiline = true;
            _exampleText.wordWrap = true;
            _exampleText.autoSize = TextFieldAutoSize.LEFT;
            _exampleText.antiAliasType = AntiAliasType.ADVANCED;
            _exampleText.width = 300;
            _exampleText.embedFonts = true;
            _exampleText.defaultTextFormat = _format;
            _exampleText.text = _lipsum;
            _exampleText.x = 50;
            _exampleText.y = 100;
            addChild(_exampleText);
        }    
 
        private function onFontSelect(fbe:FontBoxEvent):void {
            _format.font = _fontBox.font.fontName;
            _exampleText.setTextFormat(_format);
        }
    }    
 
}

which yields:

  Facebook   Pinterest   Twitter   Google+
  • Beach Ball Kinect Party
    February 15, 2011 · 4 comments
    2252
    5
    Read more
  • PV3D Image Extrusion
    September 07, 2009 · 6 comments
    2843
    3
    Read more
  • Spinny 3D Trees
    March 13, 2010 · 0 comments
    2122
    4
    Read more

Sorry, the comment form is closed at this time.

Devon O. Wolfgang

AIR | Unity3D | AR/VR

Unity Certified Developer

Technical Reviewer of “The Essential Guide to Flash CS4 AIR Development” and “Starling Game Development Essentials”

Reviewer of “The Starling Handbook”

Unity Engineer at Touch Press.

Categories
  • Actionscript (95)
  • AIR (16)
  • Flash (99)
  • Games (7)
  • Liberty (13)
  • Life (53)
  • Shaders (20)
  • Unity3D (21)
Recent Comments
  • Devon O. on Unity Ripple or Shock Wave Effect
  • Feral_Pug on Unity Ripple or Shock Wave Effect
  • bavvireal on Unity3D Endless Runner Part I – Curved Worlds
  • Danielius Vargonas on Custom Post Processing with the LWRP
  • Luca G on Unity Ripple or Shock Wave Effect
Archives
  • December 2020 (1)
  • December 2019 (1)
  • September 2019 (1)
  • February 2019 (2)
  • December 2018 (1)
  • July 2018 (1)
  • June 2018 (1)
  • May 2018 (2)
  • January 2018 (1)
  • December 2017 (2)
  • October 2017 (1)
  • September 2017 (2)
  • January 2017 (1)
  • July 2016 (1)
  • December 2015 (2)
  • March 2015 (1)
  • September 2014 (1)
  • January 2014 (1)
  • August 2013 (1)
  • July 2013 (1)
  • May 2013 (1)
  • March 2013 (2)
  • December 2012 (1)
  • November 2012 (1)
  • September 2012 (3)
  • June 2012 (2)
  • May 2012 (1)
  • April 2012 (1)
  • December 2011 (2)
  • October 2011 (3)
  • September 2011 (1)
  • August 2011 (1)
  • July 2011 (1)
  • May 2011 (2)
  • April 2011 (2)
  • March 2011 (1)
  • February 2011 (1)
  • January 2011 (2)
  • December 2010 (3)
  • October 2010 (5)
  • September 2010 (1)
  • July 2010 (2)
  • May 2010 (5)
  • April 2010 (2)
  • March 2010 (7)
  • February 2010 (5)
  • January 2010 (5)
  • December 2009 (3)
  • November 2009 (1)
  • October 2009 (5)
  • September 2009 (5)
  • August 2009 (1)
  • July 2009 (1)
  • June 2009 (2)
  • May 2009 (6)
  • April 2009 (4)
  • March 2009 (2)
  • February 2009 (4)
  • January 2009 (1)
  • December 2008 (5)
  • November 2008 (2)
  • September 2008 (1)
  • August 2008 (6)
  • July 2008 (6)
  • June 2008 (9)
  • May 2008 (4)
  • April 2008 (3)
  • March 2008 (4)
  • February 2008 (9)
  • January 2008 (7)
  • December 2007 (6)
Copyright © 2017 Devon O. Wolfgang