[gui] layouts fixes

This commit is contained in:
2019-02-28 17:52:20 +03:00
parent b3196d2295
commit 020fb23188
19 changed files with 190 additions and 162 deletions

View File

@@ -1,60 +1,73 @@
package haxework.gui;
import flash.errors.Error;
import flash.Lib;
import flash.display.DisplayObject;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.DisplayObject;
import flash.errors.Error;
import flash.events.Event;
import flash.display.Sprite;
import flash.geom.Rectangle;
import flash.Lib;
import haxework.core.IDisposable;
import haxework.signal.Signal;
class Root {
class Root implements IDisposable {
public static function bind(view:IView<Dynamic>, autoSize:Bool = true) {
new Root(view, autoSize);
}
public static var instance(default, null):Root;
public var view(default, null):IView<Dynamic>;
public var autoSize(default, default):Bool;
public function new(view:IView<Dynamic>, autoSize:Bool = true) {
if (instance != null) throw new Error("Only one instance");
instance = this;
this.view = view;
this.autoSize = autoSize;
Lib.current.addChild(view.content);
var content:DisplayObject = view.content;
if (content.stage == null) {
content.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
} else {
onAddedToStage();
public static function bind(view:IView<Dynamic>, autoSize:Bool = true) {
new Root(view, autoSize);
}
View.updater.update();
}
private function onAddedToStage(?_):Void {
var content:DisplayObject = view.content;
content.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
content.stage.scaleMode = StageScaleMode.NO_SCALE;
content.stage.align = StageAlign.TOP_LEFT;
View.updater.stage = content.stage;
public static var instance(default, null):Root;
content.stage.addEventListener(Event.RESIZE, onResize);
content.stage.stageFocusRect = false;
onResize();
}
public var view(default, null):IView<Dynamic>;
public var autoSize(default, default):Bool;
public var onResize(default, null):Signal<Rectangle> = new Signal();
private function onResize(?_):Void {
var content:DisplayObject = view.content;
if (autoSize) {
view.width = content.stage.stageWidth;
view.height = content.stage.stageHeight;
} else {
view.x = (content.stage.stageWidth - view.width) / 2;
view.y = (content.stage.stageHeight - view.height) / 2;
public function new(view:IView<Dynamic>, autoSize:Bool = true) {
if (instance != null) throw new Error("Only one instance");
instance = this;
this.view = view;
this.autoSize = autoSize;
Lib.current.addChild(view.content);
var content:DisplayObject = view.content;
if (content.stage == null) {
content.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
} else {
onAddedToStage();
}
View.updater.update();
}
L.d("Screen", content.stage.stageWidth + "x" + content.stage.stageHeight);
}
private function onAddedToStage(?_):Void {
var content:DisplayObject = view.content;
content.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
content.stage.scaleMode = StageScaleMode.NO_SCALE;
content.stage.align = StageAlign.TOP_LEFT;
View.updater.stage = content.stage;
content.stage.addEventListener(Event.RESIZE, onResizeEvent);
content.stage.stageFocusRect = false;
onResizeEvent();
}
private function onResizeEvent(?_):Void {
var content:DisplayObject = view.content;
if (autoSize) {
view.width = content.stage.stageWidth;
view.height = content.stage.stageHeight;
view.toUpdate();
} else {
view.x = (content.stage.stageWidth - view.width) / 2;
view.y = (content.stage.stageHeight - view.height) / 2;
}
onResize.emit(new Rectangle(0, 0, content.stage.stageWidth, content.stage.stageHeight));
}
public function dispose():Void {
if (view != null) {
view.content.stage.removeEventListener(Event.RESIZE, onResizeEvent);
view = null;
}
onResize.dispose();
}
}

View File

@@ -1,9 +1,10 @@
package haxework.gui;
import flash.display.Shape;
import haxework.gui.skin.Skin;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.MouseEvent;
import haxework.gui.list.ScrollBarView;
import haxework.gui.skin.Skin;
import haxework.signal.Signal;
class ScrollView extends HGroupView {
@@ -14,12 +15,12 @@ class ScrollView extends HGroupView {
public var ratio(default, null):Signal<Float> = new Signal();
public var position(default, set):Float = 0;
private var mask:Shape;
private var mask:Sprite;
public function new() {
super();
skin = [Skin.color(0x000000, 0.0)];
mask = new Shape();
mask = new Sprite();
content.addChild(mask);
content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent);
}
@@ -32,7 +33,7 @@ class ScrollView extends HGroupView {
private function set_view(value:IView<Dynamic>):IView<Dynamic> {
view = value;
views = [view, scroll];
view.content.mask = mask;
cast(view.content, DisplayObject).mask = mask;
return view;
}
@@ -42,7 +43,8 @@ class ScrollView extends HGroupView {
ratio.connect(function(ratio) {
if (scroll.ratio == ratio) return;
scroll.ratio = ratio;
//scroll.visible = scroll.inLayout = ratio < 1;
scroll.visible = ratio < 1;
scroll.geometry.skipLayout = ratio >= 1;
});
scroll.onScroll.connect(function(position) this.position = position);
return scroll;
@@ -65,7 +67,7 @@ class ScrollView extends HGroupView {
view.y = - position * view.height;
// mask redraw
mask.graphics.clear();
mask.graphics.beginFill(0, 0);
mask.graphics.beginFill(0xffffff);
mask.graphics.drawRect(0, 0, width, height);
mask.graphics.endFill();
}

View File

@@ -10,8 +10,8 @@ import haxework.text.BitmapTextField;
import haxework.text.TextUtil;
class TextLayout {
public var hAlign(default, default):HAlign = HAlign.NONE;
public var vAlign(default, default):VAlign = VAlign.NONE;
public var hAlign(default, default):HAlign = NONE;
public var vAlign(default, default):VAlign = NONE;
public function new() {}
}
@@ -53,7 +53,7 @@ class TextView extends SpriteView implements ITextView {
textFormat.font = "Arial";
textFormat.size = 16;
textFormat.leading = 0;
textFormat.align = TextFormatAlign.CENTER;
textFormat.align = TextFormatAlign.LEFT;
content.addChild(textField);
}
@@ -157,21 +157,6 @@ class TextView extends SpriteView implements ITextView {
textField.setTextFormat(textFormat);
updateTextSize();
placeTextField(textField);
/*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
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);
@@ -187,15 +172,13 @@ class TextView extends SpriteView implements ITextView {
textField.height = geometry.size.content.height;
textField.x = switch (layout.hAlign) {
case HAlign.NONE: 0;
case HAlign.LEFT: geometry.padding.left;
case HAlign.LEFT | HAlign.NONE: geometry.padding.left;
case HAlign.CENTER: (width - textField.width) / 2 + geometry.padding.left - geometry.padding.right;
case HAlign.RIGHT: width - textField.width - geometry.padding.right;
default: 0;
}
textField.y = switch (layout.vAlign) {
case VAlign.NONE: 0;
case VAlign.TOP: geometry.padding.top;
case VAlign.TOP | VAlign.NONE: geometry.padding.top;
case VAlign.MIDDLE: (height - geometry.size.content.height) / 2 + geometry.padding.top - geometry.padding.bottom;
case VAlign.BOTTOM: height - geometry.size.content.height - geometry.padding.bottom;
default: 0;

View File

@@ -84,7 +84,6 @@ class View<C:DisplayObject> implements IView<C> {
}
private function set_width(value:Float):Float {
//trace('${this.id}.width = $value');
if (width != value) {
width = value;
toRedraw();
@@ -93,7 +92,6 @@ class View<C:DisplayObject> implements IView<C> {
}
private function set_height(value:Float):Float {
//trace('${this.id}.height = $value');
if (height != value) {
height = value;
toRedraw();
@@ -148,6 +146,7 @@ class Updater {
private function set_stage(value:Stage):Stage {
value.addEventListener(Event.ENTER_FRAME, update);
value.addEventListener(Event.ENTER_FRAME, redraw);
return value;
}
@@ -160,19 +159,18 @@ class Updater {
}
public function update(?_):Void {
var t = Date.now().getTime();
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();
}
t = Date.now().getTime() - t;
if (t > 10) trace("UPDATE(" + t + ")");
}
}

View File

@@ -1,6 +1,5 @@
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;
@@ -155,25 +154,25 @@ class Geometry {
public function get_width():SizeValue {
if (size.percent.width > -1) {
return SizeValue.PERCENT(size.percent.width);
return PERCENT(size.percent.width);
}
var result = size.fixed.width;
if (result < 0) {
result = size.content.width;
}
result += padding.horizontal;
return SizeValue.FIXED(result);
return FIXED(result);
}
public function get_height():SizeValue {
if (size.percent.height > -1) {
return SizeValue.PERCENT(size.percent.height);
return PERCENT(size.percent.height);
}
var result = size.fixed.height;
if (result < 0) {
result = size.content.height;
}
result += padding.vertical;
return SizeValue.FIXED(result);
return FIXED(result);
}
}

View File

@@ -11,8 +11,8 @@ class DefaultLayout implements ILayout {
public var margin(default, default):Float;
public function new() {
hAlign = HAlign.NONE;
vAlign = VAlign.NONE;
hAlign = NONE;
vAlign = NONE;
margin = 0;
}
@@ -41,48 +41,48 @@ class DefaultLayout implements ILayout {
private function setViewWidth(group:IGroupView, view:IView<Dynamic>):Void {
switch (view.geometry.width) {
case SizeValue.FIXED(value):
case FIXED(value):
view.width = value;
case SizeValue.PERCENT(value):
case PERCENT(value):
view.width = value / 100 * (group.width - view.geometry.margin.horizontal - group.geometry.padding.horizontal);
}
}
private function setViewHeight(group:IGroupView, view:IView<Dynamic>):Void {
switch (view.geometry.height) {
case SizeValue.FIXED(value):
case FIXED(value):
view.height = value;
case SizeValue.PERCENT(value):
case 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;
if (align == NONE) align = hAlign;
switch (align) {
case HAlign.LEFT | HAlign.NONE:
case LEFT | NONE:
view.x = group.geometry.padding.left + view.geometry.margin.left;
case HAlign.CENTER:
case 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:
case 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;
if (align == NONE) align = vAlign;
switch (align) {
case VAlign.TOP | VAlign.NONE:
case TOP | NONE:
view.y = group.geometry.padding.top + view.geometry.margin.top;
case VAlign.MIDDLE:
case 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:
case BOTTOM:
view.y = group.height - view.height - group.geometry.padding.bottom - view.geometry.margin.bottom;
}
}

View File

@@ -19,9 +19,9 @@ class HorizontalLayout extends DefaultLayout {
for (view in views) {
switch (view.geometry.width) {
case SizeValue.PERCENT(value):
case PERCENT(value):
leftSize -= (view.geometry.margin.horizontal);
case SizeValue.FIXED(value):
case FIXED(value):
fixedSize += (value + view.geometry.margin.horizontal);
}
setViewHeight(group, view);
@@ -35,20 +35,19 @@ class HorizontalLayout extends DefaultLayout {
leftSize -= fixedSize;
for (view in views) {
switch (view.geometry.width) {
case SizeValue.PERCENT(value):
case PERCENT(value):
view.width = value / 100 * leftSize;
fixedSize += view.width + view.geometry.margin.horizontal;
case SizeValue.FIXED(value):
case 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 _:
case LEFT | NONE: x = group.geometry.padding.left;
case CENTER: x = (group.width - fixedSize) / 2 + group.geometry.padding.left - group.geometry.padding.right;
case RIGHT: x = group.width - fixedSize - group.geometry.padding.right;
}
for (view in views) {

View File

@@ -15,9 +15,9 @@ class VerticalLayout extends DefaultLayout {
for (view in views) {
switch (view.geometry.height) {
case SizeValue.PERCENT(value):
case PERCENT(value):
leftSize -= (view.geometry.margin.vertical);
case SizeValue.FIXED(value):
case FIXED(value):
fixedSize += (value + view.geometry.margin.vertical);
}
setViewWidth(group, view);
@@ -31,20 +31,19 @@ class VerticalLayout extends DefaultLayout {
leftSize -= fixedSize;
for (view in views) {
switch (view.geometry.height) {
case SizeValue.PERCENT(value):
case PERCENT(value):
view.height = value / 100 * leftSize;
fixedSize += view.height + view.geometry.margin.vertical;
case SizeValue.FIXED(value):
case 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 _:
case TOP | NONE: y = group.geometry.padding.top;
case MIDDLE: y = (group.height - fixedSize) / 2 + group.geometry.padding.top - group.geometry.padding.bottom;
case BOTTOM: y = group.height - fixedSize - group.geometry.padding.bottom;
}
for (view in views) {

View File

@@ -16,7 +16,7 @@ class HListView<D> extends ListView<D> {
}
override private function recalcSize(item:IListItemView<D>):Void {
var itemSize = switch(item.geometry.width) {
itemSize = switch(item.geometry.width) {
case SizeValue.FIXED(value): value + item.geometry.margin.horizontal + box.layout.margin;
case _: 0;
}
@@ -27,6 +27,8 @@ class HListView<D> extends ListView<D> {
override private function set_offsetDiff(value:Float):Float {
box.geometry.padding.left = -value * itemSize;
mask.geometry.margin.left = -box.geometry.padding.left;
box.toUpdate();
mask.toUpdate();
return super.set_offsetDiff(value);
}

View File

@@ -1,5 +1,6 @@
package haxework.gui.list;
import haxework.gui.core.HAlign;
import haxework.gui.list.ListView.IListItemView;
import haxework.gui.skin.ColorSkin;
@@ -12,6 +13,8 @@ class LabelListItem<T> extends LabelView implements IListItemView<T> {
super();
geometry.size.percent.width = 100;
geometry.size.fixed.height = 20;
geometry.padding = 8;
layout.hAlign = HAlign.LEFT;
}
private function set_data(value:T):T {
data = value;

View File

@@ -16,7 +16,7 @@ class VListView<D> extends ListView<D> {
}
override private function recalcSize(item:IListItemView<D>):Void {
var itemSize = switch(item.geometry.height) {
itemSize = switch(item.geometry.height) {
case SizeValue.FIXED(value): value + item.geometry.margin.vertical + box.layout.margin;
case _: 0;
}
@@ -27,6 +27,8 @@ class VListView<D> extends ListView<D> {
override private function set_offsetDiff(value:Float):Float {
box.geometry.padding.top = -value * itemSize;
mask.geometry.margin.top = -box.geometry.padding.top;
box.toUpdate();
mask.toUpdate();
return super.set_offsetDiff(value);
}

View File

@@ -18,7 +18,6 @@ class ResMap<T> extends StringMap<T> {
}
public function put(key:String, value:T):Void {
trace(key, value);
set(key, value);
if (listeners.exists(key)) {
for (f in listeners.get(key)) call(f, value);

View File

@@ -23,4 +23,4 @@ class TextUtil {
#end
return new Point(_textWidth, _textHeight);
}
}
}