diff --git a/haxework/gui/ButtonView.hx b/haxework/gui/ButtonView.hx index 83e2226..290f218 100755 --- a/haxework/gui/ButtonView.hx +++ b/haxework/gui/ButtonView.hx @@ -82,6 +82,6 @@ class ButtonView extends LabelView { } } -interface ButtonViewListener { +typedef ButtonViewListener = { public function onPress(view:ButtonView):Void; } \ No newline at end of file diff --git a/haxework/gui/GuiBuilder.hx b/haxework/gui/GuiBuilder.hx index f100625..7a3b2c3 100755 --- a/haxework/gui/GuiBuilder.hx +++ b/haxework/gui/GuiBuilder.hx @@ -24,7 +24,7 @@ class GuiBuilder { private function new() {} - public static function build(data:Dynamic, links:Dynamic):Dynamic { + public static function build(data:Dynamic, ?links:Dynamic):Dynamic { var type:String = data.type; Reflect.deleteField(data, "type"); var object:Dynamic = instance(type); @@ -32,7 +32,7 @@ class GuiBuilder { return object; } - private static function fill(object:Dynamic, data:Dynamic, links:Dynamic):Void { + private static function fill(object:Dynamic, data:Dynamic, ?links:Dynamic):Void { var fields:Array = Reflect.fields(data); for (field in fields) { var value:Dynamic = Reflect.field(data, field); diff --git a/haxework/gui/ITextView.hx b/haxework/gui/ITextView.hx index f71e9e7..afad85c 100755 --- a/haxework/gui/ITextView.hx +++ b/haxework/gui/ITextView.hx @@ -1,9 +1,12 @@ package haxework.gui; +import flash.text.TextFormatAlign; + interface ITextView extends IView { - public var textField(default, null):T; - public var text(default, set):String; - public var fontFamily(default, set):String; - public var fontColor(default, set):Int; - public var fontSize(default, set):Float; + public var textField(default, null):T; + public var text(default, set):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; } diff --git a/haxework/gui/IView.hx b/haxework/gui/IView.hx index 84d2a58..74adc9b 100755 --- a/haxework/gui/IView.hx +++ b/haxework/gui/IView.hx @@ -38,6 +38,7 @@ interface IView { public var skin(default, set):ISkin>; public var parent(default, null):Null>; + public var inLayout(default, set):Bool; public function update():Void; public function invalidate():Void; diff --git a/haxework/gui/TextView.hx b/haxework/gui/TextView.hx index b88911c..6b45106 100755 --- a/haxework/gui/TextView.hx +++ b/haxework/gui/TextView.hx @@ -1,5 +1,6 @@ package haxework.gui; +import flash.text.TextFormatAlign; import haxework.gui.skin.ISize; import flash.text.TextFormat; import flash.display.Sprite; @@ -9,9 +10,11 @@ class TextView extends View implements ITextView { public var textField(default, null):TextField; public var text(default, set):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; + private var textFormat:TextFormat; public function new() { @@ -32,6 +35,14 @@ class TextView extends View implements ITextView { return text; } + private function set_align(value:TextFormatAlign):TextFormatAlign { + if (align != value) { + textFormat.align = align = value; + invalidate(); + } + return align; + } + private function set_fontFamily(value:String):String { if (fontFamily != value) { fontFamily = value; @@ -64,6 +75,9 @@ class TextView extends View implements ITextView { if (contentSize && !Std.is(skin, ISize)) { width = textField.width; height = textField.height; + } else { + textField.width = width; + textField.height = height; } super.update(); } diff --git a/haxework/gui/View.hx b/haxework/gui/View.hx index d2c6e1b..bd0a284 100755 --- a/haxework/gui/View.hx +++ b/haxework/gui/View.hx @@ -48,6 +48,7 @@ class View implements IView { public var skin(default, set):ISkin>; public var parent(default, null):Null>; + public var inLayout(default, set):Bool; public function new() { id = Type.getClassName(Type.getClass(this)) + counter++; @@ -60,6 +61,7 @@ class View implements IView { margins = 0; vAlign = VAlign.NONE; hAlign = HAlign.NONE; + inLayout = true; } private function currentSkin():ISkin> { @@ -239,6 +241,14 @@ class View implements IView { invalidate(); return skin; } + + private function set_inLayout(value:Bool):Bool { + if (inLayout != value) { + inLayout = value; + invalidateParent(); + } + return inLayout; + } } diff --git a/haxework/gui/layout/DefaultLayout.hx b/haxework/gui/layout/DefaultLayout.hx index a690674..eb9fc23 100755 --- a/haxework/gui/layout/DefaultLayout.hx +++ b/haxework/gui/layout/DefaultLayout.hx @@ -19,6 +19,20 @@ class DefaultLayout implements ILayout { } } + private function filterViews(group:IGroupView, views:Array>):Array> { + return Lambda.array(Lambda.filter(views, function(view:IView):Bool { + return if (view.inLayout) { + true; + } else { + setViewWidth(group, view); + setViewHeight(group, view); + placeViewHorizontal(group, view); + placeViewVertical(group, view); + false; + } + })); + } + private function setViewWidth(group:IGroupView, view:IView):Void { if (view.widthType == SizeType.PERCENT) { view.w = view.pWidth / 100 * (group.width - view.leftMargin - view.rightMargin - group.leftPadding - group.rightPadding); diff --git a/haxework/gui/layout/HorizontalLayout.hx b/haxework/gui/layout/HorizontalLayout.hx index b89762e..26f25d1 100755 --- a/haxework/gui/layout/HorizontalLayout.hx +++ b/haxework/gui/layout/HorizontalLayout.hx @@ -1,5 +1,6 @@ package haxework.gui.layout; +import haxework.core.Tuple; import haxework.gui.core.HAlign; import haxework.gui.core.SizeType; @@ -10,6 +11,8 @@ class HorizontalLayout extends DefaultLayout { } override public function place(group:IGroupView, views:Array>):Void { + views = filterViews(group, views); + var fixedSize:Float = group.layoutMargin * (views.length - 1); var leftSize:Float = group.width - group.leftPadding - group.rightPadding; var maxHeight:Float = 0; diff --git a/haxework/gui/layout/VerticalLayout.hx b/haxework/gui/layout/VerticalLayout.hx index 5c33586..e096c5f 100755 --- a/haxework/gui/layout/VerticalLayout.hx +++ b/haxework/gui/layout/VerticalLayout.hx @@ -10,6 +10,8 @@ class VerticalLayout extends DefaultLayout { } override public function place(group:IGroupView, views:Array>):Void { + views = filterViews(group, views); + var fixedSize:Float = group.layoutMargin * (views.length - 1); var leftSize:Float = group.height - group.topPadding - group.bottomPadding; var maxWidth:Float = 0; diff --git a/haxework/gui/list/ListView.hx b/haxework/gui/list/ListView.hx new file mode 100755 index 0000000..4112cfc --- /dev/null +++ b/haxework/gui/list/ListView.hx @@ -0,0 +1,98 @@ +package haxework.gui.list; + +import flash.events.MouseEvent; +import haxework.gui.core.HAlign; +import flash.display.Sprite; +import haxework.gui.skin.ISkin; + +class ListView extends VGroupView { + + public var data(default, set):Array; + public var renderer(null, set):IRenderer; + public var offset(default, set):Int; + + private var scroll:ScrollView; + private var size(default, set):Int; + + private var items:Array; + + public function new() { + super(); + offset = 0; + scroll = new ScrollView(); + scroll.inLayout = false; + scroll.pHeight = 100; + scroll.width = 5; + scroll.hAlign = HAlign.RIGHT; + scroll.position = 0; + scroll.ratio = 1; + addView(scroll); + items = new Array(); + content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); + } + + private function onMouseWheel(event:MouseEvent):Void { + offset = Math.round(Math.min(Math.max(0, offset -= event.delta*3), data.length - size)); + } + + private function set_offset(value:Int):Int { + if (offset != value) { + offset = value; + render(); + } + return offset; + } + + private function set_data(value:Array):Array { + data = value; + render(); + return data; + } + + private function set_renderer(value:IRenderer):IRenderer { + renderer = value; + render(); + return renderer; + } + + private function render():Void { + if (data != null && renderer != null) { + scroll.ratio = Math.min(1.0, size / data.length); + scroll.position = (offset / data.length); + for (i in 0...size) { + var view:V = items[i]; + if (data[offset + i] == null) break; + renderer.render(view, data[offset + i]); + } + } + } + + override public function update():Void { + super.update(); + var item:V = renderer.factory(); + size = Math.round(height / item.height); + render(); + } + + private function set_size(value:Int):Int { + if (size != value) { + size = value; + for (item in items) removeView(item); + items = new Array(); + var item:V = renderer.factory(); + var newSize = Math.round(height / item.height); + for (i in 0...size) { + item = renderer.factory(); + items.push(item); + addView(item); + } + } + return size; + } +} + +interface IRenderer { + public function factory():V; + public function render(view:V, data:D):Void; +} + diff --git a/haxework/gui/list/ScrollView.hx b/haxework/gui/list/ScrollView.hx new file mode 100755 index 0000000..70f11a8 --- /dev/null +++ b/haxework/gui/list/ScrollView.hx @@ -0,0 +1,54 @@ +package haxework.gui.list; + +import flash.display.Graphics; +import flash.display.Sprite; +import haxework.gui.skin.ISkin; +import haxework.gui.View; + +class ScrollView extends View { + + public var position(default, set):Float; + public var ratio(default, set):Float; + + public function new() { + super(); + skin = untyped new ScrollSkin(); + } + + private function set_position(value:Float):Float { + if (position != value) { + position = value; + invalidate(); + } + return position; + } + + private function set_ratio(value:Float):Float { + if (ratio != value) { + ratio = value; + invalidate(); + } + return ratio; + } +} + +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(); + } +} \ No newline at end of file diff --git a/haxework/gui/skin/ColorSkin.hx b/haxework/gui/skin/ColorSkin.hx index 96be217..ba802b0 100755 --- a/haxework/gui/skin/ColorSkin.hx +++ b/haxework/gui/skin/ColorSkin.hx @@ -6,15 +6,17 @@ import flash.display.Sprite; class ColorSkin implements ISkin> { public var color(default, default):Int; + public var alpha(default, default):Float; - public function new(?color:Int = 0xffffff) { + public function new(?color:Int = 0xfffff, ?alpha:Float = 1.0) { this.color = color; + this.alpha = alpha; } public function draw(view:IView):Void { var graphics:Graphics = view.content.graphics; graphics.clear(); - graphics.beginFill(color); + graphics.beginFill(color, alpha); graphics.drawRect(0, 0, view.width, view.height); graphics.endFill(); } diff --git a/haxework/gui/skin/ProgressSkin.hx b/haxework/gui/skin/ProgressSkin.hx index f87cfc5..c1bc421 100755 --- a/haxework/gui/skin/ProgressSkin.hx +++ b/haxework/gui/skin/ProgressSkin.hx @@ -9,6 +9,8 @@ class ProgressSkin implements ISkin { public var foreColor:Int; public var backColor:Int; + public function new() {} + public function draw(view:ProgressView):Void { var graphics:Graphics = view.content.graphics; graphics.clear(); diff --git a/haxework/log/BaseLogger.hx b/haxework/log/BaseLogger.hx index 37c4ea6..38998d7 100755 --- a/haxework/log/BaseLogger.hx +++ b/haxework/log/BaseLogger.hx @@ -1,5 +1,6 @@ package haxework.log; +import flash.events.ErrorEvent; import flash.errors.Error; import haxework.log.ILogger.LogLevel; @@ -8,13 +9,19 @@ class BaseLogger implements ILogger { public function new() {} public function log(level:LogLevel, tag:String, message:String, ?error:Dynamic, ?p:haxe.PosInfos):Void { - var s:String = "[" + level + "] " + tag + " - " + message + (error == null ? "" : " {" + error2strign(error) + "}"); - write(s, p); + write(buildString(level, tag, message, error), p); + } + + private function buildString(level:LogLevel, tag:String, message:String, ?error:Dynamic):String { + return "[" + level + "] " + tag + " - " + message + (error == null ? "" : " {" + error2strign(error) + "}"); } private function error2strign(error:Dynamic):String { return if (Std.is(error, Error)) { cast(error, Error).getStackTrace(); + } else if (Std.is(error, ErrorEvent)) { + var event:ErrorEvent = cast(error, ErrorEvent); + event.type + " - " + event.text; } else { Std.string(error); }