[gui] add view geometry

This commit is contained in:
2019-02-27 16:57:31 +03:00
parent 71995ef672
commit d819271cd3
35 changed files with 841 additions and 1084 deletions

View File

@@ -50,19 +50,19 @@ class ButtonView extends LabelView {
private function onMouseOver(event:MouseEvent):Void {
overed = true;
invalidate();
toRedraw();
}
private function onMouseOut(event:MouseEvent):Void {
overed = false;
invalidate();
toRedraw();
}
private function onMouseDown(event:MouseEvent):Void {
downed = true;
if (content.stage != null) {
content.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
invalidate();
toRedraw();
}
}
@@ -70,7 +70,7 @@ class ButtonView extends LabelView {
downed = false;
if (content.stage != null) {
content.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
invalidate();
toRedraw();
}
}
@@ -78,15 +78,15 @@ class ButtonView extends LabelView {
if (disabled != value) {
disabled = value;
content.buttonMode = !disabled;
invalidate();
toRedraw();
}
return disabled;
}
private function get_state():ButtonState {
#if mobile
return downed ? ButtonState.DOWN : ButtonState.UP;
#else
return downed ? ButtonState.DOWN : ButtonState.UP;
#else
return (downed && overed) ? ButtonState.DOWN : overed ? ButtonState.OVER : ButtonState.UP;
#end
}

View File

@@ -1,11 +1,8 @@
package haxework.gui;
import flash.display.DisplayObjectContainer;
import haxework.gui.core.VAlign;
import haxework.gui.core.HAlign;
import haxework.gui.layout.DefaultLayout;
import haxework.gui.layout.ILayout;
import flash.display.Sprite;
class GroupView extends SpriteView implements IGroupView {
public var container(get, null):DisplayObjectContainer;
@@ -13,30 +10,33 @@ class GroupView extends SpriteView implements IGroupView {
public var views(default, set):Array<IView<Dynamic>>;
public var layout(default, default):ILayout;
public var layoutVAlign(default, set):VAlign;
public var layoutHAlign(default, set):HAlign;
public var layoutMargin(default, set):Float = 0;
public var leftPadding(default, set):Float;
public var rightPadding(default, set):Float;
public var topPadding(default, set):Float;
public var bottomPadding(default, set):Float;
public var padding(null, set):Float;
public var paddings(null, set):Array<Float>;
private var viewsById:Map<String, IView<Dynamic>>;
public function new(?layout:ILayout) {
super();
this.layout = layout == null ? new DefaultLayout() : layout;
padding = 0;
//layoutMargin = 0;
layoutHAlign = HAlign.CENTER;
layoutVAlign = VAlign.MIDDLE;
views = [];
viewsById = new Map<String, IView<Dynamic>>();
}
override private function set_width(value:Float):Float {
if (width != value) {
width = value;
toUpdate();
toRedraw();
}
return width;
}
override private function set_height(value:Float):Float {
if (height != value) {
height = value;
toUpdate();
toRedraw();
}
return height;
}
inline private function get_container():DisplayObjectContainer {
return content;
}
@@ -64,7 +64,7 @@ class GroupView extends SpriteView implements IGroupView {
viewsById.set(view.id, view);
if (view.content != null) content.addChild(view.content);
view.parent = this;
invalidate();
toUpdate();
return view;
}
@@ -74,7 +74,7 @@ class GroupView extends SpriteView implements IGroupView {
viewsById.set(view.id, view);
if (view.content != null) content.addChild(view.content);
view.parent = this;
invalidate();
toUpdate();
return view;
}
@@ -83,7 +83,7 @@ class GroupView extends SpriteView implements IGroupView {
viewsById.set(view.id, view);
content.addChild(view.content);
view.parent = this;
invalidate();
toUpdate();
return view;
}
@@ -92,7 +92,7 @@ class GroupView extends SpriteView implements IGroupView {
viewsById.remove(view.id);
views.remove(view);
if (view.content != null) content.removeChild(view.content);
invalidate();
toUpdate();
return view;
}
@@ -128,78 +128,4 @@ class GroupView extends SpriteView implements IGroupView {
}
}
}
private function set_layoutVAlign(value:VAlign):VAlign {
if (layoutVAlign != value) {
layoutVAlign = value;
invalidate();
}
return layoutVAlign;
}
private function set_layoutHAlign(value:HAlign):HAlign {
if (layoutHAlign != value) {
layoutHAlign = value;
invalidate();
}
return layoutHAlign;
}
private function set_layoutMargin(value:Float):Float {
if (layoutMargin != value) {
layoutMargin = value;
invalidate();
}
return layoutMargin;
}
private function set_leftPadding(value:Float):Float {
if (leftPadding != value) {
leftPadding = value;
invalidate();
}
return leftPadding;
}
private function set_rightPadding(value:Float):Float {
if (rightPadding != value) {
rightPadding = value;
invalidate();
}
return rightPadding;
}
private function set_topPadding(value:Float):Float {
if (topPadding != value) {
topPadding = value;
invalidate();
}
return topPadding;
}
private function set_bottomPadding(value:Float):Float {
if (bottomPadding != value) {
bottomPadding = value;
invalidate();
}
return bottomPadding;
}
private function set_padding(value:Float):Float {
paddings = [value];
return value;
}
private function set_paddings(value:Array<Float>):Array<Float> {
switch (value) {
case [m]:
leftPadding = rightPadding = topPadding = bottomPadding = m;
case [a, b]:
leftPadding = rightPadding = a;
topPadding = bottomPadding = b;
}
invalidate();
invalidateParent();
return value;
}
}

View File

@@ -1,10 +0,0 @@
package haxework.gui;
interface HasPaddings {
public var leftPadding(default, set):Float;
public var rightPadding(default, set):Float;
public var topPadding(default, set):Float;
public var bottomPadding(default, set):Float;
public var padding(null, set):Float;
public var paddings(null, set):Array<Float>;
}

View File

@@ -5,21 +5,23 @@ import haxework.gui.core.HAlign;
import haxework.gui.core.VAlign;
import haxework.gui.layout.ILayout;
interface IGroupView extends IView<Dynamic> extends HasPaddings {
public var container(get, null):DisplayObjectContainer;
interface IGroupView extends IView<Dynamic> {
public var container(get, null):DisplayObjectContainer;
public var views(default, set):Array<IView<Dynamic>>;
public var layout(default, default):ILayout;
public var views(default, set):Array<IView<Dynamic>>;
public var layout(default, default):ILayout;
public var layoutVAlign(default, set):VAlign;
public var layoutHAlign(default, set):HAlign;
public var layoutMargin(default, set):Float;
public function addView(view:IView<Dynamic>):IView<Dynamic>;
public function addView(view:IView<Dynamic>):IView<Dynamic>;
public function addViewFirst(view:IView<Dynamic>):IView<Dynamic>;
public function insertView(view:IView<Dynamic>, index:Int):IView<Dynamic>;
public function removeView(view:IView<Dynamic>):IView<Dynamic>;
public function removeAllViews():Void;
public function removeViewById(id:String):IView<Dynamic>;
public function findViewById<V:IView<Dynamic>>(id:String, ?clazz:Class<V>):Null<V>;
public function addViewFirst(view:IView<Dynamic>):IView<Dynamic>;
public function insertView(view:IView<Dynamic>, index:Int):IView<Dynamic>;
public function removeView(view:IView<Dynamic>):IView<Dynamic>;
public function removeAllViews():Void;
public function removeViewById(id:String):IView<Dynamic>;
public function findViewById<V:IView<Dynamic>>(id:String, ?clazz:Class<V>):Null<V>;
}

View File

@@ -4,7 +4,7 @@ import flash.text.TextField;
import haxework.gui.IView;
import flash.text.TextFormatAlign;
interface ITextView extends IView<Dynamic> extends HasPaddings {
interface ITextView extends IView<Dynamic> {
public var textField(default, null):TextField;
public var text(get, set):String;
public var align(default, set):TextFormatAlign;

View File

@@ -1,55 +1,36 @@
package haxework.gui;
import flash.display.DisplayObject;
import haxework.gui.core.VAlign;
import haxework.gui.core.HAlign;
import haxework.gui.core.SizeType;
import haxework.gui.core.Geometry;
import haxework.gui.skin.ISkin.SkinSet;
interface IView<C:DisplayObject> {
public var id(default, default):String;
public var id(default, default):String;
public var x(default, set):Float;
public var y(default, set):Float;
public var x(default, set):Float;
public var y(default, set):Float;
public var w(default, set):Float;
public var h(default, set):Float;
public var width(default, set):Float;
public var height(default, set):Float;
public var r(default, set):Float;
public var geometry(default, default):Geometry;
public var widthType(default, null):SizeType;
public var heightType(default, null):SizeType;
public var content(default, null):C;
public var skin(default, set):SkinSet;
public var width(get, set):Float;
public var height(get, set):Float;
public var parent(default, null):Null<IGroupView>;
public var pWidth(default, set):Float;
public var pHeight(default, set):Float;
public var visible(default, set):Bool;
public var index(default, set):Int;
public var mouseEnabled(default, set):Bool;
public var contentSize(default, set):Bool;
public function update():Void;
public var hAlign(default, set):HAlign;
public var vAlign(default, set):VAlign;
public function redraw():Void;
public var leftMargin(default, set):Float;
public var rightMargin(default, set):Float;
public var topMargin(default, set):Float;
public var bottomMargin(default, set):Float;
public var margin(null, set):Float;
public var margins(null, set):Array<Float>;
public function toUpdate():Void;
public var content(default, null):C;
public var skin(default, set):SkinSet;
public function toRedraw():Void;
public var parent(default, null):Null<IGroupView>;
public var inLayout(default, set):Bool;
public var visible(default, set):Bool;
public var index(default, set):Int;
public var mouseEnabled(default, set):Bool;
public function update():Void;
public function invalidate():Void;
public function remove():Void;
public function remove():Void;
}

View File

@@ -1,8 +1,5 @@
package haxework.gui;
import haxework.gui.core.HAlign;
import haxework.gui.core.VAlign;
class LabelView extends TextView {
public function new() {
@@ -11,7 +8,5 @@ class LabelView extends TextView {
textField.selectable = false;
textField.wordWrap = false;
textField.multiline = true;
layoutHAlign = HAlign.CENTER;
layoutVAlign = VAlign.MIDDLE;
}
}

View File

@@ -42,7 +42,7 @@ class ScrollView extends HGroupView {
ratio.connect(function(ratio) {
if (scroll.ratio == ratio) return;
scroll.ratio = ratio;
scroll.visible = scroll.inLayout = ratio < 1;
//scroll.visible = scroll.inLayout = ratio < 1;
});
scroll.onScroll.connect(function(position) this.position = position);
return scroll;
@@ -55,7 +55,7 @@ class ScrollView extends HGroupView {
private function set_position(value:Float):Float {
position = Math.min(Math.max(0, value), 1 - (height / view.height));
scroll.position = position;
invalidate();
toUpdate();
return position;
}

View File

@@ -8,9 +8,9 @@ class SpriteView extends View<Sprite> {
super(new Sprite());
}
override public function update():Void {
override public function redraw():Void {
this.content.graphics.clear();
super.update();
super.redraw();
}
#if dev_layout

View File

@@ -1,13 +1,11 @@
package haxework.gui;
import haxework.text.TextUtil;
import haxework.text.BitmapTextField;
import flash.text.TextFieldAutoSize;
import haxework.gui.core.HAlign;
import haxework.gui.core.VAlign;
import flash.text.TextFormatAlign;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import haxework.text.BitmapTextField;
import haxework.text.TextUtil;
class TextView extends SpriteView implements ITextView {
@@ -21,38 +19,24 @@ class TextView extends SpriteView implements ITextView {
public var fontSize(default, set):Int;
public var fontBold(default, set):Bool;
public var layoutHAlign(default, set):HAlign;
public var layoutVAlign(default, set):VAlign;
public var fill(default, set):Bool = true;
public var leftPadding(default, set):Float = 0.0;
public var rightPadding(default, set):Float = 0.0;
public var topPadding(default, set):Float = 0.0;
public var bottomPadding(default, set):Float = 0.0;
public var padding(null, set):Float;
public var paddings(null, set):Array<Float>;
public var shadow(default, set):Bool;
public var shadowColor(default, set):Int;
private var textFormat:TextFormat;
private var _textWidth:Float;
private var _textHeight:Float;
public function new() {
super();
layoutHAlign = HAlign.CENTER;
layoutVAlign = VAlign.MIDDLE;
textField = buildTextField();
textField.width = 1;
textField.height = 1;
textField.multiline = true;
textField.wordWrap = true;
#if dev_layout
textField.borderColor = 0xff0000;
textField.border = true;
#end
textField.borderColor = 0xff0000;
textField.border = true;
#end
textFormat = textField.defaultTextFormat;
textFormat.font = "Arial";
textFormat.size = 16;
@@ -63,8 +47,8 @@ class TextView extends SpriteView implements ITextView {
private function buildTextField():TextField {
#if bitmap_text
return new BitmapTextField();
#else
return new BitmapTextField();
#else
return new TextField();
#end
}
@@ -72,27 +56,11 @@ class TextView extends SpriteView implements ITextView {
private function set_fill(value:Bool):Bool {
if (fill != value) {
fill = value;
invalidate();
toUpdate();
}
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;
}
@@ -100,7 +68,7 @@ class TextView extends SpriteView implements ITextView {
private function set_text(value:String):String {
if (_text != value) {
_text = value;
invalidate();
toUpdate();
}
return _text;
}
@@ -109,7 +77,7 @@ class TextView extends SpriteView implements ITextView {
if (align != value) {
align = value;
textFormat.align = value;
invalidate();
toUpdate();
}
return align;
}
@@ -118,7 +86,7 @@ class TextView extends SpriteView implements ITextView {
if (fontFamily != value) {
fontFamily = value;
textFormat.font = fontFamily;
invalidate();
toUpdate();
}
return fontFamily;
}
@@ -126,7 +94,7 @@ class TextView extends SpriteView implements ITextView {
private function set_fontEmbed(value:Bool):Bool {
if (fontEmbed != value) {
fontEmbed = value;
invalidate();
toUpdate();
}
return fontEmbed;
}
@@ -135,7 +103,7 @@ class TextView extends SpriteView implements ITextView {
if (fontColor != value) {
fontColor = value;
textFormat.color = fontColor;
invalidate();
toUpdate();
}
return fontColor;
}
@@ -144,7 +112,7 @@ class TextView extends SpriteView implements ITextView {
if (fontSize != value) {
fontSize = value;
textFormat.size = fontSize;
invalidate();
toUpdate();
}
return fontSize;
}
@@ -153,7 +121,7 @@ class TextView extends SpriteView implements ITextView {
if (fontBold != value) {
fontBold = value;
textFormat.bold = fontBold;
invalidate();
toUpdate();
}
return fontBold;
}
@@ -164,8 +132,8 @@ class TextView extends SpriteView implements ITextView {
private function updateTextSize():Void {
var size = TextUtil.getSize(textField);
_textWidth = size.x;
_textHeight = size.y;
geometry.size.content.width = size.x;
geometry.size.content.height = size.y;
}
override public function update():Void {
@@ -176,21 +144,21 @@ class TextView extends SpriteView implements ITextView {
if (t != null) textField.text = t;
textField.setTextFormat(textFormat);
updateTextSize();
if (contentSize && _text != null && _text.length > 0) {
/*if (false && _text != null && _text.length > 0) {
#if html5
var h = _textHeight;
var w = _textWidth;
//if (h > textFormat.size * 1.5) h = h / 2;
textField.height = h;
textField.width = w;
#end
var h = _textHeight;
var w = _textWidth;
//if (h > textFormat.size * 1.5) h = h / 2;
textField.height = h;
textField.width = w;
#end
width = textField.width + leftPadding + rightPadding;
height = textField.height + topPadding + bottomPadding;
textField.x = leftPadding;
textField.y = topPadding;
} else {
placeTextField(textField);
}
}*/
//ToDo:
//var t:Point = content.localToGlobal(new Point(textField.x, textField.y));
//t.x = Math.round(t.x);
@@ -202,7 +170,7 @@ class TextView extends SpriteView implements ITextView {
}
private function placeTextField(textField:TextField):Void {
textField.width = width;
/*textField.width = width;
textField.height = _textHeight;
textField.x = switch (layoutHAlign) {
@@ -218,7 +186,7 @@ class TextView extends SpriteView implements ITextView {
case VAlign.MIDDLE: (height - _textHeight) / 2 + topPadding - bottomPadding;
case VAlign.BOTTOM: height - _textHeight - bottomPadding;
default: 0;
}
}*/
}
override private function set_mouseEnabled(value:Bool):Bool {
@@ -226,57 +194,6 @@ class TextView extends SpriteView implements ITextView {
return super.set_mouseEnabled(value);
}
private function set_leftPadding(value:Float):Float {
if (leftPadding != value) {
leftPadding = value;
invalidate();
}
return leftPadding;
}
private function set_rightPadding(value:Float):Float {
if (rightPadding != value) {
rightPadding = value;
invalidate();
}
return rightPadding;
}
private function set_topPadding(value:Float):Float {
if (topPadding != value) {
topPadding = value;
invalidate();
}
return topPadding;
}
private function set_bottomPadding(value:Float):Float {
if (bottomPadding != value) {
bottomPadding = value;
invalidate();
}
return bottomPadding;
}
private function set_padding(value:Float):Float {
paddings = [value];
return value;
}
private function set_paddings(value:Array<Float>):Array<Float> {
switch (value) {
case [m]:
leftPadding = rightPadding = topPadding = bottomPadding = m;
case [a, b]:
leftPadding = rightPadding = a;
topPadding = bottomPadding = b;
}
invalidate();
invalidateParent();
return value;
}
private function set_shadow(value) {
if (Std.is(textField, BitmapTextField)) {
cast(textField, BitmapTextField).shadow = value;

View File

@@ -1,44 +1,43 @@
package haxework.gui;
import flash.display.Sprite;
import haxework.gui.skin.ISkin.SkinSet;
class ToggleButtonView extends ButtonView {
public var on(default, set):Bool;
public var onSkin(default, set):SkinSet;
public var on(default, set):Bool;
public var onSkin(default, set):SkinSet;
public var onText(default, set):String;
public var onText(default, set):String;
public function new() {
super();
}
private function set_on(value:Bool):Bool {
on = value;
invalidate();
return on;
}
private function set_onSkin(value:SkinSet):SkinSet {
onSkin = value;
invalidate();
return onSkin;
}
private function currentSkin():SkinSet {
return on ? onSkin : skin;
}
private function set_onText(value:String):String {
if (onText != value) {
onText = value;
invalidate;
public function new() {
super();
}
return onText;
}
override private function currentText():String {
return on && onText != null ? onText : super.currentText();
}
private function set_on(value:Bool):Bool {
on = value;
toRedraw();
return on;
}
private function set_onSkin(value:SkinSet):SkinSet {
onSkin = value;
toRedraw();
return onSkin;
}
private function currentSkin():SkinSet {
return on ? onSkin : skin;
}
private function set_onText(value:String):String {
if (onText != value) {
onText = value;
toUpdate();
}
return onText;
}
override private function currentText():String {
return on && onText != null ? onText : super.currentText();
}
}

View File

@@ -1,13 +1,10 @@
package haxework.gui;
import Array;
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
import flash.display.Stage;
import flash.events.Event;
import haxework.gui.core.HAlign;
import haxework.gui.core.SizeType;
import haxework.gui.core.VAlign;
import haxework.gui.core.Geometry;
import haxework.gui.skin.ISkin.SkinSet;
class View<C:DisplayObject> implements IView<C> {
@@ -20,37 +17,15 @@ class View<C:DisplayObject> implements IView<C> {
public var x(default, set):Float;
public var y(default, set):Float;
public var w(default, set):Float;
public var h(default, set):Float;
public var width(default, set):Float;
public var height(default, set):Float;
public var r(default, set):Float;
public var widthType(default, null):SizeType;
public var heightType(default, null):SizeType;
public var width(get, set):Float;
public var height(get, set):Float;
public var pWidth(default, set):Float;
public var pHeight(default, set):Float;
public var contentSize(default, set):Bool;
public var hAlign(default, set):HAlign;
public var vAlign(default, set):VAlign;
public var leftMargin(default, set):Float;
public var rightMargin(default, set):Float;
public var topMargin(default, set):Float;
public var bottomMargin(default, set):Float;
public var margin(null, set):Float;
public var margins(null, set):Array<Float>;
public var geometry(default, default):Geometry;
public var content(default, null):C;
public var skin(default, set):SkinSet;
public var parent(default, null):Null<IGroupView>;
public var inLayout(default, set):Bool;
public var visible(default, set):Bool;
public var index(default, set):Int;
@@ -63,29 +38,28 @@ class View<C:DisplayObject> implements IView<C> {
y = 0;
width = 1;
height = 1;
margin = 0;
vAlign = VAlign.NONE;
hAlign = HAlign.NONE;
inLayout = true;
geometry = new Geometry();
visible = true;
index = -1;
skin = [];
}
public function invalidate():Void {
updater.invalidate(this);
public function toRedraw():Void {
updater.toRedraw(this);
}
private function invalidateParent():Void {
public function toUpdate():Void {
updater.toUpdate(this);
}
private function toUpdateParent():Void {
if (parent != null)
updater.invalidate(parent);
updater.toUpdate(parent);
}
public function update():Void {
if (content != null) {
content.x = x;
content.y = y;
}
public function update():Void {}
public function redraw():Void {
for (skin in this.skin) {
skin.draw(this);
}
@@ -97,189 +71,40 @@ class View<C:DisplayObject> implements IView<C> {
private function set_x(value:Float):Float {
if (x != value) {
x = value;
invalidate();
x = content.x = value;
}
return x;
}
private function set_y(value:Float):Float {
if (y != value) {
y = value;
invalidate();
y = content.y = value;
}
return y;
}
private function set_w(value:Float):Float {
if (w != value) {
w = value;
if (!Math.isNaN(r) && r > 0) h = w / r;
invalidate();
}
return w;
}
private function set_h(value:Float):Float {
if (h != value) {
h = value;
if (!Math.isNaN(r) && r > 0) w = h * r;
invalidate();
}
return h;
}
private function set_r(value:Float):Float {
if (r != value) {
r = value;
invalidate();
invalidateParent();
}
return r;
}
private function get_width():Float {
return w;
}
private function get_height():Float {
return h;
}
private function set_width(value:Float):Float {
if (w != value || widthType != SizeType.NORMAL) {
w = value;
widthType = SizeType.NORMAL;
invalidate();
invalidateParent();
trace('${this.id}.width = $value');
if (width != value) {
width = value;
toRedraw();
}
return w;
return width;
}
private function set_height(value:Float):Float {
if (h != value || heightType != SizeType.NORMAL) {
h = value;
heightType = SizeType.NORMAL;
invalidate();
invalidateParent();
trace('${this.id}.height = $value');
if (height != value) {
height = value;
toRedraw();
}
return h;
}
private function set_pWidth(value:Float):Float {
if (pWidth != value || widthType != SizeType.PERCENT) {
pWidth = value;
widthType = SizeType.PERCENT;
invalidate();
invalidateParent();
}
return pWidth;
}
private function set_pHeight(value:Float):Float {
if (pHeight != value || heightType != SizeType.PERCENT) {
pHeight = value;
heightType = SizeType.PERCENT;
invalidate();
invalidateParent();
}
return pHeight;
}
private function set_contentSize(value:Bool):Bool {
if (contentSize != value) {
contentSize = value;
invalidate();
invalidateParent();
}
return contentSize;
}
private function set_hAlign(value:HAlign):HAlign {
if (hAlign != value) {
hAlign = value;
invalidate();
invalidateParent();
}
return hAlign;
}
private function set_vAlign(value:VAlign):VAlign {
if (vAlign != value) {
vAlign = value;
invalidate();
invalidateParent();
}
return vAlign;
}
private function set_leftMargin(value:Float):Float {
if (leftMargin != value) {
leftMargin = value;
invalidate();
invalidateParent();
}
return leftMargin;
}
private function set_rightMargin(value:Float):Float {
if (rightMargin != value) {
rightMargin = value;
invalidate();
invalidateParent();
}
return rightMargin;
}
private function set_topMargin(value:Float):Float {
if (topMargin != value) {
topMargin = value;
invalidate();
invalidateParent();
}
return topMargin;
}
private function set_bottomMargin(value:Float):Float {
if (bottomMargin != value) {
bottomMargin = value;
invalidate();
invalidateParent();
}
return bottomMargin;
}
private function set_margin(value:Float):Float {
margins = [value];
return value;
}
private function set_margins(value:Array<Float>):Array<Float> {
switch (value) {
case [m]:
leftMargin = rightMargin = topMargin = bottomMargin = m;
case [a, b]:
leftMargin = rightMargin = a;
topMargin = bottomMargin = b;
}
invalidate();
invalidateParent();
return value;
return height;
}
private function set_skin(value:SkinSet):SkinSet {
skin = value;
invalidate();
return skin;
}
private function set_inLayout(value:Bool):Bool {
if (inLayout != value) {
inLayout = value;
invalidateParent();
}
return inLayout;
this.skin = value;
toRedraw();
return this.skin;
}
private function set_visible(value:Bool):Bool {
@@ -293,7 +118,7 @@ class View<C:DisplayObject> implements IView<C> {
private function set_index(value:Int):Int {
if (index != value) {
index = value;
invalidateParent();
toUpdateParent();
}
return index;
}
@@ -313,10 +138,12 @@ class View<C:DisplayObject> implements IView<C> {
class Updater {
public var stage(null, set):Stage;
private var invalidated:Array<IView<Dynamic>>;
private var updateViews:Array<IView<Dynamic>>;
private var redrawViews:Array<IView<Dynamic>>;
public function new() {
invalidated = [];
updateViews = [];
redrawViews = [];
}
private function set_stage(value:Stage):Stage {
@@ -324,20 +151,25 @@ class Updater {
return value;
}
public function invalidate(view:IView<Dynamic>):Void {
if (Lambda.indexOf(invalidated, view) == -1) invalidated.push(view);
public function toUpdate(view:IView<Dynamic>):Void {
if (updateViews.indexOf(view) == -1) updateViews.push(view);
}
public function toRedraw(view:IView<Dynamic>):Void {
if (redrawViews.indexOf(view) == -1) redrawViews.push(view);
}
public function update(?_):Void {
var t = Date.now().getTime();
while (invalidated.length > 0) {
while (updateViews.length > 0) {
var v = null;
try {
v = invalidated.shift();
v.update();
} catch (error:Dynamic) {
L.e("Update", v + "", error);
}
v = updateViews.shift();
v.update();
}
while (redrawViews.length > 0) {
var v = null;
v = redrawViews.shift();
v.redraw();
}
t = Date.now().getTime() - t;
if (t > 10) trace("UPDATE(" + t + ")");

View File

@@ -0,0 +1,175 @@
package haxework.gui.core;
import haxework.gui.core.Geometry.SizeValue;
abstract Size(Array<Float>) {
public var width(get, set):Float;
public var height(get, set):Float;
inline public function new(value:Array<Float>) {
this = switch(value) {
case []: [-1, -1];
case [a]: [a, a];
case [a, b]: [a, b];
case x: x;
}
}
inline private function get_width():Float {
return this[0];
}
inline private function set_width(value:Float):Float {
return this[0] = value;
}
inline private function get_height():Float {
return this[1];
}
inline private function set_height(value:Float):Float {
return this[1] = value;
}
@:from static public inline function fromArray(value:Array<Float>):Size {
return new Size(value);
}
}
enum SizeValue {
FIXED(value:Float);
PERCENT(value:Float);
}
class SizeSet {
public var min(default, default):Size;
public var max(default, default):Size;
public var content(default, default):Size;
public var fixed(default, default):Size;
public var percent(default, default):Size;
public var stretch(null, set):Bool;
public function new() {
this.min = [];
this.max = [];
this.content = [];
this.fixed = [];
this.percent = [];
}
private function set_stretch(value:Bool):Bool {
this.percent = value ? [100] : [];
return value;
}
}
abstract Box(Array<Float>) {
public var left(get, set):Float;
public var right(get, set):Float;
public var top(get, set):Float;
public var bottom(get, set):Float;
public var vertical(get, never):Float;
public var horizontal(get, never):Float;
inline public function new(value:Array<Float>) {
this = switch(value) {
case []: [0, 0, 0, 0];
case [a]: [a, a, a, a];
case [a, b]: [a, a, b, b];
case [a, b, c, d]: [a, b, c, b];
case x: x;
}
}
inline private function get_left():Float {
return this[0];
}
inline private function set_left(value:Float):Float {
return this[0] = value;
}
inline private function get_right():Float {
return this[1];
}
inline private function set_right(value:Float):Float {
return this[1] = value;
}
inline private function get_top():Float {
return this[2];
}
inline private function set_top(value:Float):Float {
return this[2] = value;
}
inline private function get_bottom():Float {
return this[3];
}
inline private function set_bottom(value:Float):Float {
return this[3] = value;
}
inline private function get_vertical():Float {
return top + bottom;
}
inline private function get_horizontal():Float {
return left + right;
}
@:from static public inline function fromArray(value:Array<Float>):Box {
return new Box(value);
}
@:from static public inline function fromFloat(value:Float):Box {
return new Box([value]);
}
}
class Geometry {
public var padding(default, default):Box;
public var margin(default, default):Box;
public var size(default, default):SizeSet;
public var hAlign(default, default):HAlign;
public var vAlign(default, default):VAlign;
public var skipLayout(default, default):Bool;
public var width(get, never):SizeValue;
public var height(get, never):SizeValue;
public function new() {
this.padding = [];
this.margin = [];
this.size = new SizeSet();
this.hAlign = HAlign.NONE;
this.vAlign = VAlign.NONE;
this.skipLayout = false;
}
public function get_width():SizeValue {
if (size.percent.width > -1) {
return SizeValue.PERCENT(size.percent.width);
}
var result = size.fixed.width;
if (result < 0) {
result = size.content.width;
}
result += padding.horizontal;
return SizeValue.FIXED(result);
}
public function get_height():SizeValue {
if (size.percent.height > -1) {
return SizeValue.PERCENT(size.percent.height);
}
var result = size.fixed.height;
if (result < 0) {
result = size.content.height;
}
result += padding.vertical;
return SizeValue.FIXED(result);
}
}

View File

@@ -1,8 +1,8 @@
package haxework.gui.core;
@:enum abstract HAlign(String) from String to String {
var NONE = "NONE";
var LEFT = "LEFT";
var CENTER = "CENTER";
var RIGHT = "RIGHT";
}
var NONE = "NONE";
var LEFT = "LEFT";
var CENTER = "CENTER";
var RIGHT = "RIGHT";
}

View File

@@ -1,6 +0,0 @@
package haxework.gui.core;
enum SizeType {
NORMAL;
PERCENT;
}

View File

@@ -1,8 +1,8 @@
package haxework.gui.core;
@:enum abstract VAlign(String) from String to String {
var NONE = "NONE";
var TOP = "TOP";
var MIDDLE = "MIDDLE";
var BOTTOM = "BOTTOM";
}
var NONE = "NONE";
var TOP = "TOP";
var MIDDLE = "MIDDLE";
var BOTTOM = "BOTTOM";
}

View File

@@ -68,8 +68,6 @@ class FrameSwitcher extends GroupView implements IFrameSwitcher {
views = [];
if (value.length > 0) {
for (view in value) {
view.pWidth = 100;
view.pHeight = 100;
frames.set(view.id, view);
}
}

View File

@@ -1,79 +1,89 @@
package haxework.gui.layout;
import haxework.gui.core.SizeType;
import haxework.gui.core.Geometry.SizeValue;
import haxework.gui.core.VAlign;
import haxework.gui.core.HAlign;
class DefaultLayout implements ILayout {
public function new() {
public var hAlign(default, default):HAlign;
public var vAlign(default, default):VAlign;
public var margin(default, default):Float;
}
public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void {
for (view in views) {
setViewWidth(group, view);
setViewHeight(group, view);
placeViewHorizontal(group, view);
placeViewVertical(group, view);
public function new() {
hAlign = HAlign.NONE;
vAlign = VAlign.NONE;
margin = 0;
}
}
private function filterViews(group:IGroupView, views:Array<IView<Dynamic>>):Array<IView<Dynamic>> {
return Lambda.array(Lambda.filter(views, function(view:IView<Dynamic>):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<Dynamic>):Void {
if (view.widthType == SizeType.PERCENT) {
view.w = view.pWidth / 100 * (group.width - view.leftMargin - view.rightMargin - group.leftPadding - group.rightPadding);
} else if (group.contentSize && group.width < view.width) {
group.width = view.width;
public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void {
for (view in views) {
setViewWidth(group, view);
setViewHeight(group, view);
placeViewHorizontal(group, view);
placeViewVertical(group, view);
}
}
}
private function setViewHeight(group:IGroupView, view:IView<Dynamic>):Void {
if (view.heightType == SizeType.PERCENT) {
view.h = view.pHeight / 100 * (group.height - view.topMargin - view.bottomMargin - group.topPadding - group.bottomPadding);
} else if (group.contentSize && group.height < view.height) {
group.height = view.height;
private function filterViews(group:IGroupView, views:Array<IView<Dynamic>>):Array<IView<Dynamic>> {
return Lambda.array(Lambda.filter(views, function(view:IView<Dynamic>):Bool {
return if (!view.geometry.skipLayout) {
true;
} else {
setViewWidth(group, view);
setViewHeight(group, view);
placeViewHorizontal(group, view);
placeViewVertical(group, view);
false;
}
}));
}
}
private function placeViewHorizontal(group:IGroupView, view:IView<Dynamic>):Void {
var align:HAlign = view.hAlign;
if (align == HAlign.NONE) align = group.layoutHAlign;
switch (align) {
case HAlign.LEFT:
view.x = group.leftPadding + view.leftMargin;
case HAlign.CENTER:
view.x = (group.width - view.width) / 2 + (group.leftPadding - group.rightPadding) + (view.leftMargin - view.rightMargin);
case HAlign.RIGHT:
view.x = group.width - view.width - group.rightPadding - view.rightMargin;
case HAlign.NONE:
private function setViewWidth(group:IGroupView, view:IView<Dynamic>):Void {
switch (view.geometry.width) {
case SizeValue.FIXED(value):
view.width = value;
case SizeValue.PERCENT(value):
view.width = value / 100 * (group.width - view.geometry.margin.horizontal - group.geometry.padding.horizontal);
}
}
}
private function placeViewVertical(group:IGroupView, view:IView<Dynamic>):Void {
var align:VAlign = view.vAlign;
if (align == VAlign.NONE) align = group.layoutVAlign;
switch (align) {
case VAlign.TOP:
view.y = group.topPadding + view.topMargin;
case VAlign.MIDDLE:
view.y = (group.height - view.height) / 2 + (group.topPadding - group.bottomPadding) + (view.topMargin - view.bottomMargin);
case VAlign.BOTTOM:
view.y = group.height - view.height - group.bottomPadding - view.bottomMargin;
case VAlign.NONE:
private function setViewHeight(group:IGroupView, view:IView<Dynamic>):Void {
switch (view.geometry.height) {
case SizeValue.FIXED(value):
view.height = value;
case SizeValue.PERCENT(value):
view.height = value / 100 * (group.height - view.geometry.margin.vertical - group.geometry.padding.vertical);
}
}
private function placeViewHorizontal(group:IGroupView, view:IView<Dynamic>):Void {
var align:HAlign = view.geometry.hAlign;
if (align == HAlign.NONE) align = hAlign;
switch (align) {
case HAlign.LEFT | HAlign.NONE:
view.x = group.geometry.padding.left + view.geometry.margin.left;
case HAlign.CENTER:
view.x = (group.width - view.width) / 2 +
(group.geometry.padding.left - group.geometry.padding.right) +
(view.geometry.margin.left - view.geometry.margin.right);
case HAlign.RIGHT:
view.x = group.width - view.width - group.geometry.padding.right - view.geometry.margin.right;
}
}
private function placeViewVertical(group:IGroupView, view:IView<Dynamic>):Void {
var align:VAlign = view.geometry.vAlign;
if (align == VAlign.NONE) align = vAlign;
switch (align) {
case VAlign.TOP | VAlign.NONE:
view.y = group.geometry.padding.top + view.geometry.margin.top;
case VAlign.MIDDLE:
view.y = (group.height - view.height) / 2 +
(group.geometry.padding.top - group.geometry.padding.bottom) +
(view.geometry.margin.top - view.geometry.margin.bottom);
case VAlign.BOTTOM:
view.y = group.height - view.height - group.geometry.padding.bottom - view.geometry.margin.bottom;
}
}
}
}

View File

@@ -1,55 +1,59 @@
package haxework.gui.layout;
import haxework.gui.core.Geometry.SizeValue;
import haxework.gui.core.HAlign;
import haxework.gui.core.SizeType;
class HorizontalLayout extends DefaultLayout {
public function new() {
super();
}
override public function place(group:IGroupView, views:Array<IView<Dynamic>>):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;
for (view in views) {
switch (view.widthType) {
case SizeType.NORMAL: fixedSize += (view.width + view.leftMargin + view.rightMargin);
case SizeType.PERCENT: leftSize -= (view.leftMargin + view.rightMargin);
}
setViewHeight(group, view);
placeViewVertical(group, view);
maxHeight = Math.max(maxHeight, view.height);
public function new() {
super();
}
if (group.contentSize) {
group.width = Math.max(group.width, fixedSize + group.leftPadding + group.rightPadding);
group.height = maxHeight + group.topPadding + group.bottomPadding;
}
override public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void {
views = filterViews(group, views);
leftSize -= fixedSize;
for (view in views) {
if (view.widthType == SizeType.PERCENT) {
view.w = view.pWidth / 100 * leftSize;
fixedSize += view.width + view.leftMargin + view.rightMargin;
}
}
var fixedSize:Float = margin * (views.length - 1);
var leftSize:Float = group.width - group.geometry.padding.horizontal;
var x:Float = 0;
switch (group.layoutHAlign) {
case HAlign.LEFT: x = group.leftPadding;
case HAlign.CENTER: x = (group.width - fixedSize) / 2 + group.leftPadding - group.rightPadding;
case HAlign.RIGHT: x = group.width - fixedSize - group.rightPadding;
case _:
}
var maxSize:Float = 0;
for (view in views) {
view.x = x + view.leftMargin;
x += (view.width + view.leftMargin + view.rightMargin + group.layoutMargin);
for (view in views) {
switch (view.geometry.width) {
case SizeValue.PERCENT(value):
leftSize -= (view.geometry.margin.horizontal);
case SizeValue.FIXED(value):
fixedSize += (value + view.geometry.margin.horizontal);
}
setViewHeight(group, view);
placeViewVertical(group, view);
maxSize = Math.max(maxSize, view.height);
}
group.geometry.size.content.height = maxSize;
group.geometry.size.content.width = fixedSize;
leftSize -= fixedSize;
for (view in views) {
switch (view.geometry.width) {
case SizeValue.PERCENT(value):
view.width = value / 100 * leftSize;
fixedSize += view.width + view.geometry.margin.horizontal;
case SizeValue.FIXED(value):
view.width = value;
}
}
var x:Float = 0;
switch (hAlign) {
case HAlign.LEFT: x = group.geometry.padding.left;
case HAlign.CENTER: x = (group.width - fixedSize) / 2 + group.geometry.padding.left - group.geometry.padding.right;
case HAlign.RIGHT: x = group.width - fixedSize - group.geometry.padding.right;
case _:
}
for (view in views) {
view.x = x + view.geometry.margin.left;
x += (view.width + view.geometry.margin.horizontal + margin);
}
}
}
}

View File

@@ -1,5 +1,12 @@
package haxework.gui.layout;
import haxework.gui.core.VAlign;
import haxework.gui.core.HAlign;
interface ILayout {
public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void;
public var hAlign(default, default):HAlign;
public var vAlign(default, default):VAlign;
public var margin(default, default):Float;
public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void;
}

View File

@@ -8,17 +8,13 @@ typedef Row = {
class TailLayout extends DefaultLayout {
public function new() {
super();
}
// ToDo: check group.layoutAlign
private function placeRow(group:IGroupView, y:Float, row:Row):Void {
var x:Float = (group.width - row.width) / 2;
for (v in row.views) {
v.x = x;
v.y = y + (row.height - v.height) / 2;
x += v.width + group.layoutMargin;
x += v.width + margin;
}
}
@@ -30,7 +26,9 @@ class TailLayout extends DefaultLayout {
views: [],
}
for (view in views) {
if (row.width + view.width + group.layoutMargin + group.leftMargin + group.rightMargin > group.width) {
setViewWidth(group, view);
setViewHeight(group, view);
if (row.width + view.width + margin + group.geometry.margin.horizontal > group.width) {
rows.push(row);
row = {
width: 0,
@@ -39,20 +37,18 @@ class TailLayout extends DefaultLayout {
};
}
row.views.push(view);
row.width += view.width + group.layoutMargin;
row.width += view.width + margin;
row.height = Math.max(row.height, view.height);
}
rows.push(row);
var h:Float = Lambda.fold(rows, function(row, h) return row.height + h, 0) + group.layoutMargin * (rows.length - 1);
var y:Float = Math.max(group.topMargin, (group.height - h) / 2);
var h:Float = Lambda.fold(rows, function(row, h) return row.height + h, 0) + margin * (rows.length - 1);
var y:Float = Math.max(group.geometry.margin.top, (group.height - h) / 2);
y = 0;
for (row in rows) {
placeRow(group, y, row);
y += row.height + group.layoutMargin;
}
if (group.contentSize) {
group.height = h;
y += row.height + margin;
}
group.geometry.size.content.height = h;
}
}

View File

@@ -1,55 +1,55 @@
package haxework.gui.layout;
import haxework.gui.core.VAlign;
import haxework.gui.core.SizeType;
import haxework.gui.core.Geometry.SizeValue;
class VerticalLayout extends DefaultLayout {
public function new() {
super();
}
override public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void {
views = filterViews(group, views);
override public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void {
views = filterViews(group, views);
var fixedSize:Float = margin * (views.length - 1);
var leftSize:Float = group.height - group.geometry.padding.vertical;
var fixedSize:Float = group.layoutMargin * (views.length - 1);
var leftSize:Float = group.height - group.topPadding - group.bottomPadding;
var maxWidth:Float = 0;
var maxSize:Float = 0;
for (view in views) {
switch (view.heightType) {
case SizeType.NORMAL: fixedSize += (view.height + view.topMargin + view.bottomMargin);
case SizeType.PERCENT: leftSize -= (view.topMargin + view.bottomMargin);
}
setViewWidth(group, view);
placeViewHorizontal(group, view);
maxWidth = Math.max(maxWidth, view.width);
for (view in views) {
switch (view.geometry.height) {
case SizeValue.PERCENT(value):
leftSize -= (view.geometry.margin.vertical);
case SizeValue.FIXED(value):
fixedSize += (value + view.geometry.margin.vertical);
}
setViewWidth(group, view);
placeViewHorizontal(group, view);
maxSize = Math.max(maxSize, view.width);
}
group.geometry.size.content.width = maxSize;
group.geometry.size.content.height = fixedSize;
leftSize -= fixedSize;
for (view in views) {
switch (view.geometry.height) {
case SizeValue.PERCENT(value):
view.height = value / 100 * leftSize;
fixedSize += view.height + view.geometry.margin.vertical;
case SizeValue.FIXED(value):
view.height = value;
}
}
var y:Float = 0;
switch (vAlign) {
case VAlign.TOP: y = group.geometry.padding.top;
case VAlign.MIDDLE: y = (group.height - fixedSize) / 2 + group.geometry.padding.top - group.geometry.padding.bottom;
case VAlign.BOTTOM: y = group.height - fixedSize - group.geometry.padding.bottom;
case _:
}
for (view in views) {
view.y = y + view.geometry.margin.top;
y += (view.height + view.geometry.margin.vertical + margin);
}
}
if (group.contentSize) {
group.width = maxWidth + group.leftPadding + group.rightPadding;
group.height = Math.max(group.height, fixedSize + group.topPadding + group.bottomPadding);
}
leftSize -= fixedSize;
for (view in views) {
if (view.heightType == SizeType.PERCENT) {
view.h = view.pHeight / 100 * leftSize;
fixedSize += view.height + view.topMargin + view.bottomMargin;
}
}
var y:Float = 0;
switch (group.layoutVAlign) {
case VAlign.TOP: y = group.topPadding;
case VAlign.MIDDLE: y = (group.height - fixedSize) / 2 + group.topPadding - group.bottomPadding;
case VAlign.BOTTOM: y = group.height - fixedSize - group.bottomPadding;
case _:
}
for (view in views) {
view.y = y + view.topMargin;
y += (view.height + view.topMargin + view.bottomMargin + group.layoutMargin);
}
}
}

View File

@@ -10,19 +10,19 @@ class HListView<D> extends ListView<D> {
public function new() {
super(new HorizontalLayout(), new VerticalLayout());
box.layoutHAlign = HAlign.LEFT;
box.layoutVAlign = VAlign.MIDDLE;
//box.layoutHAlign = HAlign.LEFT;
//box.layoutVAlign = VAlign.MIDDLE;
}
override private function recalcSize(item:IListItemView<D>):Void {
itemSize = item.width + item.leftMargin + item.rightMargin + box.layoutMargin;
/*itemSize = item.width + item.leftMargin + item.rightMargin + box.layoutMargin;
size = Math.ceil(Math.max(0, box.width / itemSize)) + 2;
sizeDiff = size - ((box.width - box.layoutMargin - 1) / itemSize);
sizeDiff = size - ((box.width - box.layoutMargin - 1) / itemSize);*/
}
override private function set_offsetDiff(value:Float):Float {
box.leftPadding = -value * itemSize;
mask.leftMargin = -box.leftPadding;
/*box.leftPadding = -value * itemSize;
mask.leftMargin = -box.leftPadding;*/
return super.set_offsetDiff(value);
}

View File

@@ -1,8 +1,7 @@
package haxework.gui.list;
import flash.text.TextFormatAlign;
import haxework.gui.skin.ColorSkin;
import haxework.gui.list.ListView.IListItemView;
import haxework.gui.skin.ColorSkin;
class LabelListItem<T> extends LabelView implements IListItemView<T> {
@@ -12,8 +11,7 @@ class LabelListItem<T> extends LabelView implements IListItemView<T> {
public function new() {
super();
height = 20;
pWidth = 100;
layoutHAlign = LEFT;
//pWidth = 100;
}
private function set_data(value:T):T {
data = value;

View File

@@ -10,227 +10,220 @@ import haxework.gui.core.HAlign;
class ListView<D> extends GroupView {
public var data(default, set):Array<D>;
public var factory(null, default):Class<IListItemView<D>>;
public var data(default, set):Array<D>;
public var factory(null, default):Class<IListItemView<D>>;
public var offset(default, set):Int;
private var offsetDiff(default, set):Float;
public var offset(default, set):Int;
private var offsetDiff(default, set):Float;
private var size(default, set):Int;
private var sizeDiff:Float;
private var size(default, set):Int;
private var sizeDiff:Float;
public var onItemSelect(default, null):Signal<IListItemView<D>>;
public var scroll(default, set):ScrollBarView;
public var onItemSelect(default, null):Signal<IListItemView<D>>;
public var scroll(default, set):ScrollBarView;
public var prev(default, set):ButtonView;
public var next(default, set):ButtonView;
public var prev(default, set):ButtonView;
public var next(default, set):ButtonView;
public var filter(default, set):D->Bool;
private var filteredData:Array<D>;
public var filter(default, set):D -> Bool;
private var filteredData:Array<D>;
public var selected(default, set):Array<D>;
public var selected(default, set):Array<D>;
private var main:GroupView;
private var box:GroupView;
private var mask:SpriteView;
private var itemSize:Float;
private var main:GroupView;
private var box:GroupView;
private var mask:SpriteView;
private var itemSize:Float;
public var items(default, null):Array<IListItemView<D>>;
private var itemsListeners:Map<IListItemView<D>, MouseEvent->Void>;
public var items(default, null):Array<IListItemView<D>>;
private var itemsListeners:Map<IListItemView<D>, MouseEvent -> Void>;
public function new(layout:ILayout, otherLayout:ILayout) {
super(otherLayout);
main = new GroupView(layout);
main.layoutHAlign = HAlign.CENTER;
main.layoutVAlign = VAlign.MIDDLE;
main.pWidth = 100;
main.pHeight = 100;
addView(main);
box = new GroupView(layout);
box.pWidth = 100;
box.pHeight = 100;
main.addView(box);
mask = new SpriteView();
mask.pWidth = 100;
mask.pHeight = 100;
mask.inLayout = false;
mask.skin.push(Skin.color(0xffffff));
box.content.mask = mask.content;
box.addView(mask);
onItemSelect = new Signal();
itemSize = 0;
offset = 0;
offsetDiff = 0;
sizeDiff = 0;
items = [];
itemsListeners = new Map<IListItemView<D>, MouseEvent->Void>();
selected = [];
content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent);
}
private function set_scroll(value:ScrollBarView):ScrollBarView {
if (scroll != null) {
scroll.onScroll.disconnect(onScroll);
removeView(scroll);
public function new(layout:ILayout, otherLayout:ILayout) {
super(otherLayout);
main = new GroupView(layout);
//main.layoutHAlign = HAlign.CENTER;
//main.layoutVAlign = VAlign.MIDDLE;
main.geometry.size.stretch = true;
addView(main);
box = new GroupView(layout);
box.geometry.size.stretch = true;
main.addView(box);
mask = new SpriteView();
mask.geometry.size.stretch = true;
mask.geometry.skipLayout = true;
mask.skin.push(Skin.color(0xffffff));
box.content.mask = mask.content;
box.addView(mask);
onItemSelect = new Signal();
itemSize = 0;
offset = 0;
offsetDiff = 0;
sizeDiff = 0;
items = [];
itemsListeners = new Map<IListItemView<D>, MouseEvent -> Void>();
selected = [];
content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent);
}
scroll = value;
if (scroll != null) {
scroll.onScroll.connect(onScroll);
addView(scroll);
}
invalidate();
return scroll;
}
private function set_prev(value:ButtonView):ButtonView {
if (prev != null) {
main.removeView(prev);
prev.dispose();
}
prev = value;
prev.onPress.connect(onPrevPress);
main.addViewFirst(prev);
return prev;
}
private function onPrevPress(_):Void {
offset = offset - 1;
}
private function set_next(value:ButtonView):ButtonView {
if (next != null) {
main.removeView(next);
next.dispose();
}
next = value;
next.onPress.connect(onNextPress);
main.addView(next);
return next;
}
private function onNextPress(_):Void {
offset = offset + 1;
}
public function onScroll(position:Float):Void {
var x:Float = filteredData.length * position;
var o:Int = Math.floor(x);
offsetDiff = (x - o);
offset = o;
}
private function onMouseWheelEvent(event:MouseEvent):Void {
#if flash event.preventDefault(); #end
onMouseWheel(event.delta);
}
private function onMouseWheel(value:Int):Void {}
private function set_offset(value:Int):Int {
value = NumberUtil.limitInt(value, 0, filteredData == null ? 0 : filteredData.length - size + 2);
if (offset != value) {
if (filteredData != null) {
//ToDo: constant for 2
if (value == 0) offsetDiff = 0;
if (value == filteredData.length - size + 2) offsetDiff = sizeDiff - 2;
}
offset = value;
render();
}
return offset;
}
private function set_data(value:Array<D>):Array<D> {
data = value;
render();
return data;
}
private function set_filter(value:D->Bool):D->Bool {
if (filter != value) {
filter = value;
render();
}
return filter;
}
private function set_selected(value:Array<D>):Array<D> {
if (selected != value) {
selected = value;
invalidate();
}
return selected;
}
public function render():Void {
if (data != null && factory != null) {
filteredData = filter == null ? data : data.filter(filter);
scroll.ratio = Math.min(1.0, (size - sizeDiff) / filteredData.length);
scroll.position = ((offset + offsetDiff) / filteredData.length);
for (i in 0...size) {
var item:IListItemView<D> = items[i];
var index = offset + i;
if (filteredData[index] == null) {
item.visible = false;
} else {
item.visible = true;
item.item_index = index;
item.data = filteredData[item.item_index];
private function set_scroll(value:ScrollBarView):ScrollBarView {
if (scroll != null) {
scroll.onScroll.disconnect(onScroll);
removeView(scroll);
}
}
}
}
override public function update():Void {
super.update();
recalcSize(Type.createInstance(factory, []));
render();
}
private function recalcSize(item:IListItemView<D>):Void {}
private function set_size(value:Int):Int {
if (size != value) {
size = value;
var diff:Int = size - items.length;
if (diff > 0) {
for (i in 0...diff) {
var item:IListItemView<D> = Type.createInstance(factory, []);
items.push(item);
setClickListener(item);
box.addView(item);
scroll = value;
if (scroll != null) {
scroll.onScroll.connect(onScroll);
addView(scroll);
}
} else if (diff < 0) {
for (i in 0...-diff) {
var item:IListItemView<D> = items.pop();
item.content.removeEventListener(MouseEvent.CLICK, itemsListeners.get(item));
itemsListeners.remove(item);
box.removeView(item);
toUpdate();
return scroll;
}
private function set_prev(value:ButtonView):ButtonView {
if (prev != null) {
main.removeView(prev);
prev.dispose();
}
}
prev = value;
prev.onPress.connect(onPrevPress);
main.addViewFirst(prev);
return prev;
}
return size;
}
private function set_offsetDiff(value:Float):Float {
offsetDiff = value;
return offsetDiff;
}
private function setClickListener(item:IListItemView<D>):Void {
var listener:MouseEvent->Void = function(event:MouseEvent):Void {
onItemSelect.emit(item);
private function onPrevPress(_):Void {
offset = offset - 1;
}
item.content.addEventListener(MouseEvent.CLICK, listener);
itemsListeners.set(item, listener);
}
override private function set_layoutMargin(value:Float):Float {
return box.layoutMargin = value;
}
private function set_next(value:ButtonView):ButtonView {
if (next != null) {
main.removeView(next);
next.dispose();
}
next = value;
next.onPress.connect(onNextPress);
main.addView(next);
return next;
}
private function onNextPress(_):Void {
offset = offset + 1;
}
public function onScroll(position:Float):Void {
var x:Float = filteredData.length * position;
var o:Int = Math.floor(x);
offsetDiff = (x - o);
offset = o;
}
private function onMouseWheelEvent(event:MouseEvent):Void {
#if flash event.preventDefault(); #end
onMouseWheel(event.delta);
}
private function onMouseWheel(value:Int):Void {}
private function set_offset(value:Int):Int {
value = NumberUtil.limitInt(value, 0, filteredData == null ? 0 : filteredData.length - size + 2);
if (offset != value) {
if (filteredData != null) {
//ToDo: constant for 2
if (value == 0) offsetDiff = 0;
if (value == filteredData.length - size + 2) offsetDiff = sizeDiff - 2;
}
offset = value;
render();
}
return offset;
}
private function set_data(value:Array<D>):Array<D> {
data = value;
render();
return data;
}
private function set_filter(value:D -> Bool):D -> Bool {
if (filter != value) {
filter = value;
render();
}
return filter;
}
private function set_selected(value:Array<D>):Array<D> {
if (selected != value) {
selected = value;
toUpdate();
}
return selected;
}
public function render():Void {
if (data != null && factory != null) {
filteredData = filter == null ? data : data.filter(filter);
scroll.ratio = Math.min(1.0, (size - sizeDiff) / filteredData.length);
scroll.position = ((offset + offsetDiff) / filteredData.length);
for (i in 0...size) {
var item:IListItemView<D> = items[i];
var index = offset + i;
if (filteredData[index] == null) {
item.visible = false;
} else {
item.visible = true;
item.item_index = index;
item.data = filteredData[item.item_index];
}
}
}
}
override public function update():Void {
super.update();
recalcSize(Type.createInstance(factory, []));
render();
}
private function recalcSize(item:IListItemView<D>):Void {}
private function set_size(value:Int):Int {
if (size != value) {
size = value;
var diff:Int = size - items.length;
if (diff > 0) {
for (i in 0...diff) {
var item:IListItemView<D> = Type.createInstance(factory, []);
items.push(item);
setClickListener(item);
box.addView(item);
}
} else if (diff < 0) {
for (i in 0...-diff) {
var item:IListItemView<D> = items.pop();
item.content.removeEventListener(MouseEvent.CLICK, itemsListeners.get(item));
itemsListeners.remove(item);
box.removeView(item);
}
}
}
return size;
}
private function set_offsetDiff(value:Float):Float {
offsetDiff = value;
return offsetDiff;
}
private function setClickListener(item:IListItemView<D>):Void {
var listener:MouseEvent -> Void = function(event:MouseEvent):Void {
onItemSelect.emit(item);
}
item.content.addEventListener(MouseEvent.CLICK, listener);
itemsListeners.set(item, listener);
}
}
interface IListItemView<D> extends IView<Dynamic> {
public var item_index(default, default):Int;
public var data(default, set):D;
public var item_index(default, default):Int;
public var data(default, set):D;
}

View File

@@ -7,60 +7,60 @@ import flash.events.MouseEvent;
class ScrollBarView extends SpriteView {
public var position(default, set):Float;
public var ratio(default, set):Float;
public var position(default, set):Float;
public var ratio(default, set):Float;
public var onScroll(default, null):Signal<Float> = new Signal();
public var onScroll(default, null):Signal<Float> = new Signal();
private var mousePosition:Float;
private var mousePosition:Float;
public function new() {
super();
content.buttonMode = true;
ratio = 1;
position = 0;
content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownEvent);
}
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));
onMouseDown(p);
}
private function onMouseMoveEvent(event:MouseEvent):Void {
var p:Point = content.globalToLocal(new Point(event.stageX, event.stageY));
onMouseMove(p);
}
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) {
position = value;
invalidate();
public function new() {
super();
content.buttonMode = true;
ratio = 1;
position = 0;
content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownEvent);
}
return position;
}
private function set_ratio(value:Float):Float {
if (ratio != value) {
ratio = value;
invalidate();
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));
onMouseDown(p);
}
return ratio;
}
public function dispose():Void {
onScroll.dispose();
}
private function onMouseMoveEvent(event:MouseEvent):Void {
var p:Point = content.globalToLocal(new Point(event.stageX, event.stageY));
onMouseMove(p);
}
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) {
position = value;
toRedraw();
}
return position;
}
private function set_ratio(value:Float):Float {
if (ratio != value) {
ratio = value;
toRedraw();
}
return ratio;
}
public function dispose():Void {
onScroll.dispose();
}
}

View File

@@ -10,19 +10,19 @@ class VListView<D> extends ListView<D> {
public function new() {
super(new VerticalLayout(), new HorizontalLayout());
box.layoutHAlign = HAlign.CENTER;
box.layoutVAlign = VAlign.TOP;
//box.layoutHAlign = HAlign.CENTER;
//box.layoutVAlign = VAlign.TOP;
}
override private function recalcSize(item:IListItemView<D>):Void {
itemSize = item.height + item.topMargin + item.bottomMargin + box.layoutMargin;
/*itemSize = item.height + item.topMargin + item.bottomMargin + box.layoutMargin;
size = Math.ceil(Math.max(0, box.height / itemSize)) + 2;
sizeDiff = size - ((box.height - box.layoutMargin - 1) / itemSize);
sizeDiff = size - ((box.height - box.layoutMargin - 1) / itemSize);*/
}
override private function set_offsetDiff(value:Float):Float {
box.topPadding = -value * itemSize;
mask.topMargin = -box.topPadding;
/*box.topPadding = -value * itemSize;
mask.topMargin = -box.topPadding;*/
return super.set_offsetDiff(value);
}

View File

@@ -33,9 +33,9 @@ class BitmapSkin implements ISkin<SpriteView> {
public function draw(view:SpriteView):Void {
if (image == null) return;
DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color);
if (view.contentSize) {
/*if (view.contentSize) {
view.w = image.width;
view.h = image.height;
}
}*/
}
}

View File

@@ -1,36 +0,0 @@
package haxework.gui.skin;
class SizeSkin implements ISkin<IView<Dynamic>> {
public var width(default, default):Float;
public var height(default, default):Float;
public var pHeight(default, default):Float;
public var pWidth(default, default):Float;
public function new(width:Float = -1, height:Float = -1, pHeight:Float = -1, pWidth:Float = -1) {
this.width = width;
this.height = height;
this.pHeight = pHeight;
this.pWidth = pWidth;
}
public function draw(view:IView<Dynamic>):Void {
if (pHeight != -1) {
view.pHeight = pHeight;
}
if (pWidth != -1) {
view.pWidth = pWidth;
}
if (width != -1) {
view.width = width;
}
if (height != -1) {
view.height = height;
}
}
public static function percent(pHeight:Float, pWidth:Float):SizeSkin {
return new SizeSkin(-1, -1, pHeight, pWidth);
}
public static var FILL:SizeSkin = percent(100, 100);
}

View File

@@ -16,10 +16,6 @@ class Skin {
return new BorderSkin(color, alpha, tickness);
}
public static function size(width:Float, height:Float): ISkin<Dynamic> {
return new SizeSkin(width, height);
}
public static function text(fontColor:Int, fontSize:Int, fontFamily:String = null):ISkin<ITextView> {
return new TextSkin(fontColor, fontSize, fontFamily);
}