diff --git a/haxework/gui/GuiBuilder.hx b/haxework/gui/GuiBuilder.hx index 0175d99..36ac556 100755 --- a/haxework/gui/GuiBuilder.hx +++ b/haxework/gui/GuiBuilder.hx @@ -2,6 +2,10 @@ package haxework.gui; //ToDo: +import flash.errors.Error; +import openfl.Assets; +import flash.errors.TypeError; +import flash.errors.ArgumentError; import haxework.resources.IResources; import haxework.provider.Provider; import haxework.gui.View; @@ -11,6 +15,7 @@ import haxework.gui.GroupView; import haxework.gui.HGroupView; import haxework.gui.VGroupView; import haxework.gui.TextView; +import haxework.gui.InputView; import haxework.gui.LabelView; import haxework.gui.ButtonView; import haxework.gui.ToggleButtonView; @@ -24,28 +29,66 @@ import haxework.frame.FrameSwitcher; class GuiBuilder { - private function new() {} - public static function build(data:Dynamic, ?links:Dynamic):Dynamic { + return new GuiB(data, links).build(); + } + + public static function fill(object:Dynamic, data:Dynamic, ?links:Dynamic):Void { + new GuiF(object, data, links).fill(); + } +} + +class GuiB { + + private var data:Dynamic; + private var links:Dynamic; + + public function new(data:Dynamic, ?links:Dynamic) { + this.data = data; + this.links = links; + } + + public function build():Dynamic { if (Reflect.hasField(data, "type")) { var type:String = data.type; - Reflect.deleteField(data, "type"); + //Reflect.deleteField(data, "type"); var object:Dynamic = instance(type); - fill(object, data, links); + new GuiF(object, data, links).fill(); return object; } else { - fill(data, data, links); + new GuiF(data, data, links).fill(); return data; } } - public static function fill(object:Dynamic, data:Dynamic, ?links:Dynamic):Void { + private static function instance(type:String):Dynamic { + var clazz:Class = Type.resolveClass(type); + if (clazz == null) throw new TypeError("Class \"" + type + "\" not found"); + var instance:Dynamic = Type.createInstance(clazz, []); + return instance; + } +} + +class GuiF { + + private var object:Dynamic; + private var data:Dynamic; + private var links:Dynamic; + + public function new(object:Dynamic, data:Dynamic, ?links:Dynamic) { + this.object = object; + this.data = data; + this.links = links; + } + + public function fill() { var fields:Array = Reflect.fields(data); for (field in fields) { + if (field == "type") continue; var value:Dynamic = Reflect.field(data, field); if (Std.is(value, Array)) { var a:Array = []; - for (o in cast(value, Array)) a.push(build(o, links)); + for (o in cast(value, Array)) a.push(new GuiB(o, links).build()); value = a; } else if (Std.is(value, String)) { var s:String = cast(value, String); @@ -57,9 +100,16 @@ class GuiBuilder { var e:Enum = Type.resolveEnum(a[0]); value = Type.createEnum(e, a[1]); } else if (c == "@") { - var a:Array = s.substr(1).split(":"); - //value = Reflect.field(Provider.get(IResources), a[0]).get(a[1]); - Reflect.field(Provider.get(IResources), a[0]).bind(a[1], object, field); + if (s.charAt(1) == "~") { + var a:Array = s.substr(2).split(":"); + switch (a[0]) { + case "image": Reflect.setProperty(object, field, Assets.getBitmapData(a[1])); + } + } else { + var a:Array = s.substr(1).split(":"); + //value = Reflect.field(Provider.get(IResources), a[0]).get(a[1]); + Reflect.field(Provider.get(IResources), a[0]).bind(a[1], object, field); + } continue; } else if (~/0x[A-Fa-f\d]{6}/.match(value)) { value = Std.parseInt(value); @@ -69,17 +119,15 @@ class GuiBuilder { } else if (Std.is(value, Bool)) { } else { - var o:Dynamic = build(value, links); - fill(o, value, links); + var o:Dynamic = new GuiB(value, links).build(); + new GuiF(o, value, links).fill(); value = o; } - Reflect.setProperty(object, field, value); + try { + Reflect.setProperty(object, field, value); + } catch(error:Dynamic) { + L.e("GuiBuilder", "", error); + } } } - - private static function instance(type:String):Dynamic { - var clazz:Class = Type.resolveClass(type); - var instance:Dynamic = Type.createInstance(clazz, []); - return instance; - } -} +} \ No newline at end of file diff --git a/haxework/gui/ITextView.hx b/haxework/gui/ITextView.hx index c7880b1..934d2e7 100755 --- a/haxework/gui/ITextView.hx +++ b/haxework/gui/ITextView.hx @@ -5,7 +5,7 @@ import flash.text.TextFormatAlign; interface ITextView extends IView { public var textField(default, null):T; - public var text(default, set):String; + public var text(get, set):String; public var align(default, set):TextFormatAlign; public var fontFamily(default, set):String; public var fontColor(default, set):Int; diff --git a/haxework/gui/ImageView.hx b/haxework/gui/ImageView.hx index e93d9fd..d6f0d87 100755 --- a/haxework/gui/ImageView.hx +++ b/haxework/gui/ImageView.hx @@ -6,13 +6,13 @@ import flash.display.BitmapData; class ImageView extends SpriteView { - private var image(default, set):BitmapData; + public var image(default, set):BitmapData; public function new() { super(); } - public function set_image(value:BitmapData):BitmapData { + private function set_image(value:BitmapData):BitmapData { if (image != value) { image = value; skin = untyped new BitmapSkin(image); diff --git a/haxework/gui/InputView.hx b/haxework/gui/InputView.hx new file mode 100755 index 0000000..6903280 --- /dev/null +++ b/haxework/gui/InputView.hx @@ -0,0 +1,12 @@ +package haxework.gui; + +import flash.events.TextEvent; +import flash.text.TextFieldType; + +class InputView extends TextView { + + public function new() { + super(); + textField.type = TextFieldType.INPUT; + } +} \ No newline at end of file diff --git a/haxework/gui/LabelView.hx b/haxework/gui/LabelView.hx index 306e4d2..dc8d8c9 100755 --- a/haxework/gui/LabelView.hx +++ b/haxework/gui/LabelView.hx @@ -1,19 +1,17 @@ package haxework.gui; +import haxework.gui.core.HAlign; +import haxework.gui.core.VAlign; import flash.text.TextFieldAutoSize; class LabelView extends TextView { public function new() { super(); + fill = false; textField.selectable = false; textField.wordWrap = false; - textField.autoSize = TextFieldAutoSize.LEFT; - } - - override public function update():Void { - super.update(); - textField.x = (width - textField.width) / 2; - textField.y = (height - textField.height) / 2; + layoutHAlign = HAlign.CENTER; + layoutVAlign = VAlign.MIDDLE; } } diff --git a/haxework/gui/TextView.hx b/haxework/gui/TextView.hx index d0b77b4..f9e426b 100755 --- a/haxework/gui/TextView.hx +++ b/haxework/gui/TextView.hx @@ -1,5 +1,8 @@ package haxework.gui; +import flash.text.TextFieldAutoSize; +import haxework.gui.core.HAlign; +import haxework.gui.core.VAlign; import flash.text.TextFormatAlign; import haxework.gui.skin.ISize; import flash.text.TextFormat; @@ -9,16 +12,24 @@ import flash.text.TextField; class TextView extends SpriteView implements ITextView { public var textField(default, null):TextField; - public var text(default, set):String; + public var text(get, set):String; + private var _text:String; public var align(default, set):TextFormatAlign; public var fontFamily(default, set):String; public var fontColor(default, set):Int; public var fontSize(default, set):Float; + public var layoutHAlign(default, set):HAlign; + public var layoutVAlign(default, set):VAlign; + public var fill(default, set):Bool = true; + public var paddings(default, set):Float = 0.0; + private var textFormat:TextFormat; public function new() { super(); + layoutHAlign = HAlign.NONE; + layoutVAlign = VAlign.NONE; textField = new TextField(); textField.width = 1; textField.height = 1; @@ -29,13 +40,48 @@ class TextView extends SpriteView implements ITextView { content.addChild(textField); } - private function set_text(value:String):String { - if (text != value) { - text = value; - //textField.text = text; + private function set_paddings(value:Float):Float { + if (paddings != value) { + paddings = value; invalidate(); } - return text; + return paddings; + } + + private function set_fill(value:Bool):Bool { + if (fill != value) { + fill = value; + invalidate(); + } + return fill; + } + + private function set_layoutHAlign(value:HAlign):HAlign { + if (layoutHAlign != value) { + layoutHAlign = value; + invalidate(); + } + return layoutHAlign; + } + + private function set_layoutVAlign(value:VAlign):VAlign { + if (layoutVAlign != value) { + layoutVAlign = value; + invalidate(); + } + return layoutVAlign; + } + + private function get_text():String { + return textField.text; + } + + private function set_text(value:String):String { + if (_text != value) { + _text = value; + invalidate(); + } + return _text; } private function set_align(value:TextFormatAlign):TextFormatAlign { @@ -75,13 +121,31 @@ class TextView extends SpriteView implements ITextView { override public function update():Void { textField.defaultTextFormat = textFormat; - if (text != null) textField.text = text; + textField.autoSize = fill ? TextFieldAutoSize.NONE : TextFieldAutoSize.LEFT; + if (_text != null) textField.text = _text; if (contentSize && !Std.is(skin, ISize)) { width = textField.width; height = textField.height; } else { - textField.width = width; - textField.height = height; + if (fill) { + textField.width = width - paddings * 2; + textField.height = height - paddings * 2; + textField.x = paddings; + textField.y = paddings; + } else { + textField.x = switch (layoutHAlign) { + case HAlign.NONE: 0; + case HAlign.LEFT: 0; + case HAlign.CENTER: (width - textField.width) / 2; + case HAlign.RIGHT: width - textField.width; + } + textField.y = switch (layoutVAlign) { + case VAlign.NONE: 0; + case VAlign.TOP: 0; + case VAlign.MIDDLE: (height - textField.height) / 2; + case VAlign.BOTTOM: height - textField.height; + } + } } super.update(); } diff --git a/haxework/gui/list/HListView.hx b/haxework/gui/list/HListView.hx new file mode 100755 index 0000000..11a2ff8 --- /dev/null +++ b/haxework/gui/list/HListView.hx @@ -0,0 +1,33 @@ +package haxework.gui.list; + +import haxework.gui.core.HAlign; +import haxework.gui.layout.VerticalLayout; +import haxework.gui.list.ListView.ListItem; +import haxework.gui.list.HScrollView; +import haxework.gui.core.VAlign; +import haxework.gui.layout.HorizontalLayout; + +class HListView, D> extends ListView { + + public function new() { + super(new HorizontalLayout(), new VerticalLayout()); + container.layoutHAlign = HAlign.LEFT; + container.layoutVAlign = VAlign.MIDDLE; + } + + override private function recalcSize(item:ListItem):Void { + var view:IView = item.view; + itemSize = view.width + view.leftMargin + view.rightMargin + layoutMargin; + size = Math.round(Math.max(0, width / itemSize)) + 2; + } + + override private function set_diff(value:Float):Float { + container.leftPadding = -value * itemSize; + mask.leftMargin = -container.leftPadding; + return super.set_diff(value); + } + + override private function onMouseWheel(value:Int):Void { + offset = offset + value; + } +} \ No newline at end of file diff --git a/haxework/gui/list/HScrollSkin.hx b/haxework/gui/list/HScrollSkin.hx new file mode 100755 index 0000000..49a2b9b --- /dev/null +++ b/haxework/gui/list/HScrollSkin.hx @@ -0,0 +1,26 @@ +package haxework.gui.list; + +import haxework.gui.skin.ISkin; +import flash.display.Sprite; +import flash.display.Graphics; + +class HScrollSkin implements ISkin { + + public var foreColor(default, default):Int; + public var backColor(default, default):Int; + + public function new(?foreColor:Int = 0xffffff, ?backColor:Int = 0x707070) { + this.foreColor = foreColor; + this.backColor = backColor; + } + + public function draw(view:ScrollView):Void { + var graphics:Graphics = view.content.graphics; + graphics.clear(); + graphics.beginFill(backColor); + graphics.drawRect(0, 0, view.width, view.height); + graphics.beginFill(foreColor); + graphics.drawRect(view.width * view.position, 0, view.width * view.ratio, view.height); + graphics.endFill(); + } +} \ No newline at end of file diff --git a/haxework/gui/list/HScrollView.hx b/haxework/gui/list/HScrollView.hx new file mode 100755 index 0000000..ca29a1e --- /dev/null +++ b/haxework/gui/list/HScrollView.hx @@ -0,0 +1,23 @@ +package haxework.gui.list; + +import haxework.gui.list.ScrollView.ScrollListener; +import flash.geom.Point; +import haxework.gui.list.HScrollSkin; + +class HScrollView extends ScrollView { + + public function new() { + super(); + } + + override private function onMouseDown(p:Point):Void { + mousePosition = p.x - width * position; + } + + override private function onMouseMove(p:Point):Void { + position = (p.x - mousePosition) / width; + dispatcher.dispatch(function(listener:ScrollListener):Void { + listener.onScroll(position); + }); + } +} \ No newline at end of file diff --git a/haxework/gui/list/ListView.hx b/haxework/gui/list/ListView.hx index c721fbd..cc6c6b3 100755 --- a/haxework/gui/list/ListView.hx +++ b/haxework/gui/list/ListView.hx @@ -1,5 +1,8 @@ package haxework.gui.list; +import haxework.gui.skin.ColorSkin; +import haxework.gui.core.VAlign; +import haxework.gui.layout.ILayout; import haxework.utils.NumberUtil; import haxework.dispath.Dispatcher; import haxework.dispath.IDispatcher; @@ -9,48 +12,73 @@ import haxework.gui.core.HAlign; import flash.display.Sprite; import haxework.gui.skin.ISkin; -class ListView, D> extends VGroupView implements ScrollListener { +class ListView, D> extends GroupView implements ScrollListener { public var data(default, set):Array; public var renderer(null, set):IRenderer; public var offset(default, set):Int; public var dispatcher(default, null):IDispatcher>; + public var scroll(default, set):ScrollView; - private var scroll:ScrollView; + private var container:GroupView; + private var mask:SpriteView; + private var itemSize:Float; + private var diff(default, set):Float; private var size(default, set):Int; private var items:Array>; private var itemsListeners:Map, MouseEvent->Void>; - public function new() { - super(); + public function new(layout:ILayout, otherLayout:ILayout) { + super(otherLayout); + container = new GroupView(layout); + container.pWidth = 100; + container.pHeight = 100; + addView(container); + mask = new SpriteView(); + mask.pWidth = 100; + mask.pHeight = 100; + mask.inLayout = false; + mask.skin = new ColorSkin(0xffffff); + container.content.mask = mask.content; + container.addView(mask); dispatcher = new Dispatcher>(); + itemSize = 0; offset = 0; - scroll = new ScrollView(); - scroll.dispatcher.addListener(this); - scroll.inLayout = false; - scroll.pHeight = 100; - scroll.width = 10; - scroll.hAlign = HAlign.RIGHT; - scroll.position = 0; - scroll.ratio = 1; - scroll.rightMargin = -12; - rightPadding = 12; - addView(scroll); + diff = 0; items = new Array>(); itemsListeners = new Map, MouseEvent->Void>(); - content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); + content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent); + } + + private function set_scroll(value:ScrollView):ScrollView { + if (scroll != null) { + scroll.dispatcher.removeListener(this); + removeView(scroll); + } + scroll = value; + if (scroll != null) { + scroll.dispatcher.addListener(this); + addView(scroll); + } + invalidate(); + return scroll; } public function onScroll(position:Float):Void { - offset = Math.round(data.length * position); + var x:Float = data.length * position; + offset = Math.round(x) - 1; + diff = (x - offset); } - private function onMouseWheel(event:MouseEvent):Void { - offset = offset - event.delta * 3; + private function onMouseWheelEvent(event:MouseEvent):Void { + diff = 0; + onMouseWheel(event.delta); } + private function onMouseWheel(value:Int):Void {} + private function set_offset(value:Int):Int { value = NumberUtil.limitInt(value, 0, data == null ? 0 : data.length - size); if (offset != value) { @@ -88,11 +116,12 @@ class ListView, D> extends VGroupView implements ScrollListener override public function update():Void { super.update(); - var item:ListItem = renderer.factory(); - size = Math.round(Math.max(0, height / item.view.height)); + recalcSize(renderer.factory()); render(); } + private function recalcSize(item:ListItem):Void {} + private function set_size(value:Int):Int { if (size != value) { size = value; @@ -102,20 +131,25 @@ class ListView, D> extends VGroupView implements ScrollListener var item:ListItem = renderer.factory(); items.push(item); setClickListener(item); - addView(item.view); + container.addView(item.view); } } else if (diff < 0) { for (i in 0...-diff) { var item:ListItem = items.pop(); item.view.content.removeEventListener(MouseEvent.CLICK, itemsListeners.get(item)); itemsListeners.remove(item); - removeView(item.view); + container.removeView(item.view); } } } return size; } + private function set_diff(value:Float):Float { + diff = value; + return diff; + } + private function setClickListener(item:ListItem):Void { var listener:MouseEvent->Void = function(event:MouseEvent):Void { dispatcher.dispatch(function(listener:ListViewListener):Void { diff --git a/haxework/gui/list/ScrollView.hx b/haxework/gui/list/ScrollView.hx index 71bd00d..b1fe752 100755 --- a/haxework/gui/list/ScrollView.hx +++ b/haxework/gui/list/ScrollView.hx @@ -5,10 +5,6 @@ import flash.geom.Point; import haxework.dispath.Dispatcher; import haxework.dispath.IDispatcher; import flash.events.MouseEvent; -import flash.display.Graphics; -import flash.display.Sprite; -import haxework.gui.skin.ISkin; -import haxework.gui.View; class ScrollView extends SpriteView { @@ -21,31 +17,34 @@ class ScrollView extends SpriteView { public function new() { super(); + content.buttonMode = true; + position = 0; + ratio = 1; dispatcher = new Dispatcher(); - skin = untyped new ScrollSkin(); - content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); + content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownEvent); } - private function onMouseDown(event:MouseEvent):Void { - content.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); - content.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); + private function onMouseDownEvent(event:MouseEvent):Void { + content.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveEvent); + content.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpEvent); var p:Point = content.globalToLocal(new Point(event.stageX, event.stageY)); - mousePosition = p.y - height * position; + onMouseDown(p); } - private function onMouseMove(event:MouseEvent):Void { + private function onMouseMoveEvent(event:MouseEvent):Void { var p:Point = content.globalToLocal(new Point(event.stageX, event.stageY)); - position = (p.y - mousePosition) / height; - dispatcher.dispatch(function(listener:ScrollListener):Void { - listener.onScroll(position); - }); + onMouseMove(p); } - private function onMouseUp(event:MouseEvent):Void { - content.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); - content.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); + private function onMouseUpEvent(event:MouseEvent):Void { + content.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveEvent); + content.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpEvent); } + private function onMouseDown(p:Point):Void {} + + private function onMouseMove(p:Point):Void {} + private function set_position(value:Float):Float { value = NumberUtil.limitFloat(value, 0, 1 - ratio); if (position != value) { @@ -64,27 +63,6 @@ class ScrollView extends SpriteView { } } -class ScrollSkin implements ISkin { - - public var foreColor:Int; - public var backColor:Int; - - public function new() { - foreColor = 0xffffff; - backColor = 0x505050; - } - - public function draw(view:ScrollView):Void { - var graphics:Graphics = view.content.graphics; - graphics.clear(); - graphics.beginFill(backColor); - graphics.drawRect(0, 0, view.width, view.height); - graphics.beginFill(foreColor); - graphics.drawRect(0, view.height * view.position, view.width, view.height * view.ratio); - graphics.endFill(); - } -} - interface ScrollListener { public function onScroll(position:Float):Void; } \ No newline at end of file diff --git a/haxework/gui/list/VListView.hx b/haxework/gui/list/VListView.hx new file mode 100755 index 0000000..9af9b7b --- /dev/null +++ b/haxework/gui/list/VListView.hx @@ -0,0 +1,33 @@ +package haxework.gui.list; + +import haxework.gui.core.VAlign; +import haxework.gui.list.ListView.ListItem; +import haxework.gui.layout.VerticalLayout; +import haxework.gui.list.VScrollView; +import haxework.gui.core.HAlign; +import haxework.gui.layout.HorizontalLayout; + +class VListView, D> extends ListView { + + public function new() { + super(new VerticalLayout(), new HorizontalLayout()); + container.layoutHAlign = HAlign.CENTER; + container.layoutVAlign = VAlign.TOP; + } + + override private function recalcSize(item:ListItem):Void { + var view:IView = item.view; + itemSize = view.height + view.topMargin + view.bottomMargin + layoutMargin; + size = Math.round(Math.max(0, height / itemSize)) + 1; + } + + override private function set_diff(value:Float):Float { + container.topPadding = -value * itemSize; + mask.topMargin = -container.topPadding; + return super.set_diff(value); + } + + override private function onMouseWheel(value:Int):Void { + offset = offset - value; + } +} \ No newline at end of file diff --git a/haxework/gui/list/VScrollSkin.hx b/haxework/gui/list/VScrollSkin.hx new file mode 100755 index 0000000..904c70d --- /dev/null +++ b/haxework/gui/list/VScrollSkin.hx @@ -0,0 +1,26 @@ +package haxework.gui.list; + +import haxework.gui.skin.ISkin; +import flash.display.Sprite; +import flash.display.Graphics; + +class VScrollSkin implements ISkin { + + public var foreColor(default, default):Int; + public var backColor(default, default):Int; + + public function new(?foreColor:Int = 0xffffff, ?backColor:Int = 0x707070) { + this.foreColor = foreColor; + this.backColor = backColor; + } + + public function draw(view:ScrollView):Void { + var graphics:Graphics = view.content.graphics; + graphics.clear(); + graphics.beginFill(backColor); + graphics.drawRect(0, 0, view.width, view.height); + graphics.beginFill(foreColor); + graphics.drawRect(0, view.height * view.position, view.width, view.height * view.ratio); + graphics.endFill(); + } +} \ No newline at end of file diff --git a/haxework/gui/list/VScrollView.hx b/haxework/gui/list/VScrollView.hx new file mode 100755 index 0000000..89a6eb9 --- /dev/null +++ b/haxework/gui/list/VScrollView.hx @@ -0,0 +1,23 @@ +package haxework.gui.list; + +import haxework.gui.list.ScrollView.ScrollListener; +import flash.geom.Point; +import haxework.gui.list.VScrollSkin; + +class VScrollView extends ScrollView { + + public function new() { + super(); + } + + override private function onMouseDown(p:Point):Void { + mousePosition = p.y - height * position; + } + + override private function onMouseMove(p:Point):Void { + position = (p.y - mousePosition) / height; + dispatcher.dispatch(function(listener:ScrollListener):Void { + listener.onScroll(position); + }); + } +} \ No newline at end of file diff --git a/haxework/gui/skin/BitmapSkin.hx b/haxework/gui/skin/BitmapSkin.hx index ee05f50..9e9dced 100755 --- a/haxework/gui/skin/BitmapSkin.hx +++ b/haxework/gui/skin/BitmapSkin.hx @@ -1,7 +1,10 @@ package haxework.gui.skin; +import flash.geom.Rectangle; +import flash.geom.Matrix; import flash.display.BitmapData; import haxework.gui.utils.ColorUtils; +import haxework.gui.utils.DrawUtil; import haxework.gui.ButtonView.ButtonState; import flash.display.Graphics; import flash.display.Sprite; @@ -12,11 +15,15 @@ class BitmapSkin implements ISkin implements ISize { public var height(default, null):Float; public var image(null, set):BitmapData; + public var color(default, default):Int; + public var fillType(default, default):FillType; - public function new(?image:BitmapData = null) { + public function new(?image:BitmapData = null, ?fillType = null, ?color = -1) { if (image != null) { this.image = image; } + this.fillType = fillType; + this.color = color; } private function set_image(value:BitmapData):BitmapData { @@ -30,11 +37,7 @@ class BitmapSkin implements ISkin implements ISize { public function draw(view:SpriteView):Void { if (image == null) return; - var graphics:Graphics = view.content.graphics; - graphics.clear(); - graphics.beginBitmapFill(image, null, false, true); - graphics.drawRect(0, 0, view.width, view.height); - graphics.endFill(); + DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color); } } \ No newline at end of file diff --git a/haxework/gui/skin/ButtonBitmapSkin.hx b/haxework/gui/skin/ButtonBitmapSkin.hx index 0c406d8..c4ac311 100755 --- a/haxework/gui/skin/ButtonBitmapSkin.hx +++ b/haxework/gui/skin/ButtonBitmapSkin.hx @@ -1,5 +1,7 @@ package haxework.gui.skin; +import haxework.gui.utils.DrawUtil; +import flash.geom.Rectangle; import flash.display.BitmapData; import haxework.gui.utils.ColorUtils; import haxework.gui.ButtonView.ButtonState; @@ -11,6 +13,8 @@ class ButtonBitmapSkin implements ISkin implements ISize { public var width(default, null):Float; public var height(default, null):Float; + public var fillType(default, default):FillType; + public var color(default, default):Int; public var image(null, set):BitmapData; public var upImage(null, set):BitmapData; public var overImage(null, set):BitmapData; @@ -18,11 +22,13 @@ class ButtonBitmapSkin implements ISkin implements ISize { private var images:Map; - public function new(?image:BitmapData = null) { + public function new(?image:BitmapData = null, ?fillType = null, ?color = -1) { images = new Map(); if (image != null) { this.image = image; } + this.fillType = fillType; + this.color = color; } private function set_image(value:BitmapData):BitmapData { @@ -55,11 +61,7 @@ class ButtonBitmapSkin implements ISkin implements ISize { public function draw(view:ButtonView):Void { if (images == null) return; var image:BitmapData = images.get(view.state); - var graphics:Graphics = view.content.graphics; - graphics.clear(); - graphics.beginBitmapFill(image, null, false, true); - graphics.drawRect(0, 0, view.width, view.height); - graphics.endFill(); + DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color); } } \ No newline at end of file diff --git a/haxework/gui/utils/DrawUtil.hx b/haxework/gui/utils/DrawUtil.hx new file mode 100755 index 0000000..2f1db44 --- /dev/null +++ b/haxework/gui/utils/DrawUtil.hx @@ -0,0 +1,45 @@ +package haxework.gui.utils; + +import flash.geom.Matrix; +import flash.geom.Rectangle; +import flash.display.BitmapData; +import flash.display.Graphics; + +enum FillType { + DEFAULT; + COVER; + CONTAIN; +} + +class DrawUtil { + + public static function draw(graphics:Graphics, image:BitmapData, rect:Rectangle, ?fillType:FillType = null, ?color:Int = -1):Void { + if (fillType == null) fillType = FillType.DEFAULT; + graphics.clear(); + if (color > -1) { + graphics.beginFill(color); + graphics.drawRect(rect.x, rect.y, rect.width, rect.height); + graphics.endFill(); + } + var m:Matrix = new Matrix(); + var s:Float = 1.0; + switch (fillType) { + case FillType.DEFAULT: + case FillType.CONTAIN: + s = Math.min(rect.width / image.width, rect.height / image.height); + case FillType.COVER: + s = Math.max(rect.width / image.width, rect.height / image.height); + } + m.scale(s, s); + var dx:Float = (rect.width - image.width * s) / 2; + var dy:Float = (rect.height - image.height * s) / 2; + m.translate(dx, dy); + graphics.beginBitmapFill(image, m, false, false); + rect.x = Math.max(rect.x, m.tx); + rect.y = Math.max(rect.y, m.ty); + rect.width = Math.min(rect.width, image.width * s); + rect.height = Math.min(rect.height, image.height * s); + graphics.drawRect(rect.x, rect.y, rect.width, rect.height); + graphics.endFill(); + } +} \ No newline at end of file