[gui] update

This commit is contained in:
2019-03-01 12:48:07 +03:00
parent 020fb23188
commit 3e06e5df26
22 changed files with 273 additions and 216 deletions

View File

@@ -8,8 +8,8 @@ views:
- id: tabs - id: tabs
$type: haxework.gui.HGroupView $type: haxework.gui.HGroupView
layout.margin: 5 layout.margin: 5
layout.hAlign: LEFT layout.hAlign: left
geometry.size.percent.width: 100 geometry.size.width: 100%
geometry.padding.left: 5 geometry.padding.left: 5
views: views:
- id: list_form - id: list_form

View File

@@ -8,5 +8,5 @@ views:
scroll: scroll:
$type: haxework.gui.list.VScrollBarView $type: haxework.gui.list.VScrollBarView
skin: $r:skin:scroll skin: $r:skin:scroll
geometry.size.percent.height: 100 geometry.size.height: 100%
geometry.size.fixed.width: 10 geometry.size.width: 10

View File

@@ -5,12 +5,12 @@ views:
scroll: scroll:
$type: haxework.gui.list.VScrollBarView $type: haxework.gui.list.VScrollBarView
skin: $r:skin:scroll skin: $r:skin:scroll
geometry.size.percent.height: 100 geometry.size.height: 100%
geometry.size.fixed.width: 10 geometry.size.width: 10
view: view:
id: group id: group
$type: haxework.gui.GroupView $type: haxework.gui.GroupView
geometry.size.percent.width: 100 geometry.size.width: 100%
layout.margin: 5 layout.margin: 5
layout: layout:
$type: haxework.gui.layout.TailLayout $type: haxework.gui.layout.TailLayout

View File

@@ -21,8 +21,10 @@ class ImageView extends SpriteView {
if (image != value) { if (image != value) {
image = value; image = value;
skin = [new BitmapSkin(image, FillType.DEFAULT)]; skin = [new BitmapSkin(image, FillType.DEFAULT)];
toUpdate(); //geometry.size.content.width = value.width;
toRedraw(); //geometry.size.content.height = value.height;
//toUpdate();
//toRedraw();
} }
return image; return image;
} }

View File

@@ -1,5 +1,6 @@
package haxework.gui; package haxework.gui;
import haxework.gui.core.Geometry.Position;
import flash.display.DisplayObject; import flash.display.DisplayObject;
import flash.display.Sprite; import flash.display.Sprite;
import flash.events.MouseEvent; import flash.events.MouseEvent;
@@ -44,7 +45,7 @@ class ScrollView extends HGroupView {
if (scroll.ratio == ratio) return; if (scroll.ratio == ratio) return;
scroll.ratio = ratio; scroll.ratio = ratio;
scroll.visible = ratio < 1; scroll.visible = ratio < 1;
scroll.geometry.skipLayout = ratio >= 1; scroll.geometry.position = ratio < 1 ? LAYOUT : ABSOLUTE;
}); });
scroll.onScroll.connect(function(position) this.position = position); scroll.onScroll.connect(function(position) this.position = position);
return scroll; return scroll;

View File

@@ -11,15 +11,11 @@ class SpriteView extends View<Sprite> {
override public function redraw():Void { override public function redraw():Void {
this.content.graphics.clear(); this.content.graphics.clear();
super.redraw(); super.redraw();
}
#if dev_layout #if dev_layout
override public function update():Void { var graphics = content.graphics;
super.update(); graphics.lineStyle(1, 0x00ff00);
var g:Graphics = content.graphics; graphics.drawRect(0, 0, width, height);
g.lineStyle(1, 0x00ff00); graphics.lineStyle();
g.drawRect(0, 0, width, height);
g.lineStyle();
}
#end #end
} }
}

View File

@@ -1,11 +1,11 @@
package haxework.gui; package haxework.gui;
import haxework.gui.core.VAlign;
import haxework.gui.core.HAlign;
import flash.text.TextField; import flash.text.TextField;
import flash.text.TextFieldAutoSize; import flash.text.TextFieldAutoSize;
import flash.text.TextFormat; import flash.text.TextFormat;
import flash.text.TextFormatAlign; import flash.text.TextFormatAlign;
import haxework.gui.core.HAlign;
import haxework.gui.core.VAlign;
import haxework.text.BitmapTextField; import haxework.text.BitmapTextField;
import haxework.text.TextUtil; import haxework.text.TextUtil;
@@ -172,15 +172,15 @@ class TextView extends SpriteView implements ITextView {
textField.height = geometry.size.content.height; textField.height = geometry.size.content.height;
textField.x = switch (layout.hAlign) { textField.x = switch (layout.hAlign) {
case HAlign.LEFT | HAlign.NONE: geometry.padding.left; case LEFT | NONE: geometry.padding.left;
case HAlign.CENTER: (width - textField.width) / 2 + geometry.padding.left - geometry.padding.right; case CENTER: (width - textField.width) / 2 + geometry.padding.left - geometry.padding.right;
case HAlign.RIGHT: width - textField.width - geometry.padding.right; case RIGHT: width - textField.width - geometry.padding.right;
default: 0; default: 0;
} }
textField.y = switch (layout.vAlign) { textField.y = switch (layout.vAlign) {
case VAlign.TOP | VAlign.NONE: geometry.padding.top; case TOP | NONE: geometry.padding.top;
case VAlign.MIDDLE: (height - geometry.size.content.height) / 2 + geometry.padding.top - geometry.padding.bottom; case MIDDLE: (height - geometry.size.content.height) / 2 + geometry.padding.top - geometry.padding.bottom;
case VAlign.BOTTOM: height - geometry.size.content.height - geometry.padding.bottom; case BOTTOM: height - geometry.size.content.height - geometry.padding.bottom;
default: 0; default: 0;
} }
} }

View File

@@ -1,16 +1,15 @@
package haxework.gui; package haxework.gui;
import haxework.gui.skin.ISkin.ISizeSkin;
import flash.display.DisplayObject; import flash.display.DisplayObject;
import flash.display.InteractiveObject; import flash.display.InteractiveObject;
import flash.display.Stage;
import flash.events.Event;
import haxework.gui.core.Geometry; import haxework.gui.core.Geometry;
import haxework.gui.skin.ISkin.SkinSet; import haxework.gui.skin.ISkin.SkinSet;
class View<C:DisplayObject> implements IView<C> { class View<C:DisplayObject> implements IView<C> {
private static var counter:Int = 0; private static var counter:Int = 0;
public static var updater(default, null):Updater = new Updater(); public static var updater(default, null):ViewUpdater = new ViewUpdater();
public var id(default, default):String; public var id(default, default):String;
@@ -61,6 +60,13 @@ class View<C:DisplayObject> implements IView<C> {
public function redraw():Void { public function redraw():Void {
for (skin in this.skin) { for (skin in this.skin) {
if (Std.is(skin, ISizeSkin)) {
var sizeSkin:ISizeSkin = cast skin;
if (sizeSkin.width != geometry.size.content.width || sizeSkin.height != geometry.size.content.width) {
geometry.size.content = [sizeSkin.width, sizeSkin.height];
toUpdateParent();
}
}
skin.draw(this); skin.draw(this);
} }
} }
@@ -131,46 +137,3 @@ class View<C:DisplayObject> implements IView<C> {
return mouseEnabled; return mouseEnabled;
} }
} }
class Updater {
public var stage(null, set):Stage;
private var updateViews:Array<IView<Dynamic>>;
private var redrawViews:Array<IView<Dynamic>>;
public function new() {
updateViews = [];
redrawViews = [];
}
private function set_stage(value:Stage):Stage {
value.addEventListener(Event.ENTER_FRAME, update);
value.addEventListener(Event.ENTER_FRAME, redraw);
return value;
}
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 {
while (updateViews.length > 0) {
var v = null;
v = updateViews.shift();
v.update();
}
}
public function redraw(?_):Void {
while (redrawViews.length > 0) {
var v = null;
v = redrawViews.shift();
v.redraw();
}
}
}

View File

@@ -0,0 +1,53 @@
package haxework.gui;
import flash.events.Event;
import flash.display.Stage;
class ViewUpdater {
public var stage(null, set):Stage;
private var updateViews:Array<IView<Dynamic>>;
private var redrawViews:Array<IView<Dynamic>>;
public function new() {
updateViews = [];
redrawViews = [];
}
private function set_stage(value:Stage):Stage {
value.addEventListener(Event.ENTER_FRAME, onEnterFrame);
return value;
}
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);
}
private function onEnterFrame(_):Void {
update();
redraw();
if (updateViews.length > 0) {
update();
redraw();
}
}
public function update():Void {
while (updateViews.length > 0) {
var v = null;
v = updateViews.shift();
v.update();
}
}
public function redraw():Void {
while (redrawViews.length > 0) {
var v = null;
v = redrawViews.shift();
v.redraw();
}
}
}

View File

@@ -0,0 +1,68 @@
package haxework.gui.core;
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]);
}
}

View File

@@ -1,6 +0,0 @@
package haxework.gui.core;
enum Direction {
HORIZONTAL;
VERTICAL;
}

View File

@@ -1,59 +1,20 @@
package haxework.gui.core; package haxework.gui.core;
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);
}
@:from static public inline function fromFloat(value:Float):Size {
return new Size([value]);
}
}
enum SizeValue { enum SizeValue {
FIXED(value:Float); FIXED(value:Float);
PERCENT(value:Float); PERCENT(value:Float);
} }
class SizeSet { class SizeSet {
public var min(default, default):Size;
public var max(default, default):Size;
public var content(default, default):Size; public var content(default, default):Size;
public var fixed(default, default):Size; public var fixed(default, default):Size;
public var percent(default, default):Size; public var percent(default, default):Size;
public var stretch(null, set):Bool; public var stretch(null, set):Bool;
public var width(null, set):Dynamic;
public var height(null, set):Dynamic;
public function new() { public function new() {
this.min = [];
this.max = [];
this.content = []; this.content = [];
this.fixed = []; this.fixed = [];
this.percent = []; this.percent = [];
@@ -63,73 +24,27 @@ class SizeSet {
this.percent = value ? [100] : []; this.percent = value ? [100] : [];
return value; return value;
} }
}
abstract Box(Array<Float>) { inline private function set_width(value:Dynamic):Dynamic {
public var left(get, set):Float; if (Std.is(value, Float)) {
public var right(get, set):Float; return fixed.width = value;
public var top(get, set):Float; } else {
public var bottom(get, set):Float; return percent.width = Std.parseFloat(value);
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 { inline private function set_height(value:Dynamic):Dynamic {
return this[0]; if (Std.is(value, Float)) {
return fixed.height = value;
} else {
return percent.height = Std.parseFloat(value);
}
}
} }
inline private function set_left(value:Float):Float { @:enum abstract Position(String) from String to String {
return this[0] = value; var LAYOUT = "layout";
} var ABSOLUTE = "absolute";
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 { class Geometry {
@@ -138,7 +53,7 @@ class Geometry {
public var size(default, default):SizeSet; public var size(default, default):SizeSet;
public var hAlign(default, default):HAlign; public var hAlign(default, default):HAlign;
public var vAlign(default, default):VAlign; public var vAlign(default, default):VAlign;
public var skipLayout(default, default):Bool; public var position(default, default):Position;
public var width(get, never):SizeValue; public var width(get, never):SizeValue;
public var height(get, never):SizeValue; public var height(get, never):SizeValue;
@@ -149,7 +64,7 @@ class Geometry {
this.size = new SizeSet(); this.size = new SizeSet();
this.hAlign = HAlign.NONE; this.hAlign = HAlign.NONE;
this.vAlign = VAlign.NONE; this.vAlign = VAlign.NONE;
this.skipLayout = false; this.position = Position.LAYOUT;
} }
public function get_width():SizeValue { public function get_width():SizeValue {

View File

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

View File

@@ -0,0 +1,39 @@
package haxework.gui.core;
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);
}
@:from static public inline function fromFloat(value:Float):Size {
return new Size([value]);
}
}

View File

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

View File

@@ -1,5 +1,6 @@
package haxework.gui.layout; package haxework.gui.layout;
import haxework.gui.core.Geometry.Position;
import haxework.gui.core.Geometry.SizeValue; import haxework.gui.core.Geometry.SizeValue;
import haxework.gui.core.VAlign; import haxework.gui.core.VAlign;
import haxework.gui.core.HAlign; import haxework.gui.core.HAlign;
@@ -27,14 +28,15 @@ class DefaultLayout implements ILayout {
private function filterViews(group:IGroupView, views:Array<IView<Dynamic>>):Array<IView<Dynamic>> { private function filterViews(group:IGroupView, views:Array<IView<Dynamic>>):Array<IView<Dynamic>> {
return Lambda.array(Lambda.filter(views, function(view:IView<Dynamic>):Bool { return Lambda.array(Lambda.filter(views, function(view:IView<Dynamic>):Bool {
return if (!view.geometry.skipLayout) { return switch (view.geometry.position) {
true; case ABSOLUTE:
} else {
setViewWidth(group, view); setViewWidth(group, view);
setViewHeight(group, view); setViewHeight(group, view);
placeViewHorizontal(group, view); placeViewHorizontal(group, view);
placeViewVertical(group, view); placeViewVertical(group, view);
false; false;
case LAYOUT:
true;
} }
})); }));
} }

View File

@@ -1,12 +1,13 @@
package haxework.gui.list; package haxework.gui.list;
import haxework.gui.skin.Skin; import flash.events.MouseEvent;
import haxework.signal.Signal; import haxework.gui.core.Geometry.Position;
import haxework.gui.core.HAlign;
import haxework.gui.core.VAlign; import haxework.gui.core.VAlign;
import haxework.gui.layout.ILayout; import haxework.gui.layout.ILayout;
import haxework.gui.skin.Skin;
import haxework.signal.Signal;
import haxework.utils.NumberUtil; import haxework.utils.NumberUtil;
import flash.events.MouseEvent;
import haxework.gui.core.HAlign;
class ListView<D> extends GroupView { class ListView<D> extends GroupView {
@@ -41,8 +42,8 @@ class ListView<D> extends GroupView {
public function new(layout:ILayout, otherLayout:ILayout) { public function new(layout:ILayout, otherLayout:ILayout) {
super(otherLayout); super(otherLayout);
main = new GroupView(layout); main = new GroupView(layout);
main.layout.hAlign = HAlign.CENTER; main.layout.hAlign = CENTER;
main.layout.vAlign = VAlign.MIDDLE; main.layout.vAlign = MIDDLE;
main.geometry.size.stretch = true; main.geometry.size.stretch = true;
addView(main); addView(main);
box = new GroupView(layout); box = new GroupView(layout);
@@ -50,7 +51,7 @@ class ListView<D> extends GroupView {
main.addView(box); main.addView(box);
mask = new SpriteView(); mask = new SpriteView();
mask.geometry.size.stretch = true; mask.geometry.size.stretch = true;
mask.geometry.skipLayout = true; mask.geometry.position = ABSOLUTE;
mask.skin.push(Skin.color(0xffffff)); mask.skin.push(Skin.color(0xffffff));
box.content.mask = mask.content; box.content.mask = mask.content;
box.addView(mask); box.addView(mask);

View File

@@ -2,10 +2,10 @@ package haxework.gui.skin;
import flash.display.BitmapData; import flash.display.BitmapData;
import flash.geom.Rectangle; import flash.geom.Rectangle;
import haxework.gui.skin.ISkin.ISizeSkin;
import haxework.gui.utils.DrawUtil; import haxework.gui.utils.DrawUtil;
class BitmapSkin implements ISkin<SpriteView> { class BitmapSkin implements ISkin<SpriteView> implements ISizeSkin {
public var width(default, null):Float; public var width(default, null):Float;
public var height(default, null):Float; public var height(default, null):Float;
@@ -33,7 +33,5 @@ class BitmapSkin implements ISkin<SpriteView> {
public function draw(view:SpriteView):Void { public function draw(view:SpriteView):Void {
if (image == null) return; if (image == null) return;
DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color); DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color);
view.geometry.size.content.width = image.width;
view.geometry.size.content.height = image.height;
} }
} }

View File

@@ -3,10 +3,11 @@ package haxework.gui.skin;
import flash.display.BitmapData; import flash.display.BitmapData;
import flash.geom.Rectangle; import flash.geom.Rectangle;
import haxework.gui.ButtonView.ButtonState; import haxework.gui.ButtonView.ButtonState;
import haxework.gui.skin.ISkin.ISizeSkin;
import haxework.gui.utils.BitmapUtil; import haxework.gui.utils.BitmapUtil;
import haxework.gui.utils.DrawUtil; import haxework.gui.utils.DrawUtil;
class ButtonBitmapSkin implements ISkin<ButtonView> { class ButtonBitmapSkin implements ISkin<ButtonView> implements ISizeSkin {
public var width(default, null):Float; public var width(default, null):Float;
public var height(default, null):Float; public var height(default, null):Float;
@@ -62,8 +63,5 @@ class ButtonBitmapSkin implements ISkin<ButtonView> {
if (images == null) return; if (images == null) return;
var image:BitmapData = view.disabled ? disableImage == null ? disable : disableImage : images.get(view.state); var image:BitmapData = view.disabled ? disableImage == null ? disable : disableImage : images.get(view.state);
DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color); DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color);
view.geometry.size.content.width = image.width;
view.geometry.size.content.height = image.height;
} }
} }

View File

@@ -4,4 +4,9 @@ interface ISkin<V:IView<Dynamic>> {
public function draw(view: V): Void; public function draw(view: V): Void;
} }
interface ISizeSkin {
public var width(default, null):Float;
public var height(default, null):Float;
}
typedef SkinSet = Array<ISkin<Dynamic>>; typedef SkinSet = Array<ISkin<Dynamic>>;

View File

@@ -0,0 +1,18 @@
package haxework.gui.skin;
class SizeSkin implements ISkin<IView<Dynamic>> {
public var width(default, null):Float;
public var height(default, null):Float;
public function new(width:Float, height:Float) {
this.width = width;
this.height = height;
}
public function draw(view:IView<Dynamic>):Void {
if (view.geometry.size.fixed.width != width || view.geometry.size.fixed.height != height) {
view.geometry.size.fixed = [width, height];
view.toUpdate();
}
}
}

View File

@@ -4,6 +4,10 @@ import flash.display.BitmapData;
class Skin { class Skin {
public static function size(width:Float, height:Float): ISkin<Dynamic> {
return new SizeSkin(width, height);
}
public static function bitmap(image:BitmapData): ISkin<SpriteView> { public static function bitmap(image:BitmapData): ISkin<SpriteView> {
return new BitmapSkin(image); return new BitmapSkin(image);
} }