[view] fixes
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package demo;
|
||||
|
||||
import haxework.color.Color;
|
||||
import haxework.view.skin.Skin;
|
||||
import haxework.view.theme.SkinStyle;
|
||||
import haxework.view.theme.Theme;
|
||||
|
||||
using haxework.color.ColorUtil;
|
||||
@@ -13,7 +15,7 @@ class AppTheme extends Theme {
|
||||
|
||||
override private function reload():Void {
|
||||
super.reload();
|
||||
// data.put("view", text().concat(background(colors.light)).concat(border()));
|
||||
// data.put("test", [Skin.color(0x00ffff)]);
|
||||
styles.put("view", text().concat(background(colors.light, true)));
|
||||
styles.put("test", [new SkinStyle(Skin.color(0x00ffff))]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import haxework.view.IView;
|
||||
@:view var tabs:IGroupView;
|
||||
|
||||
private function init():Void {
|
||||
switcher.change("list");
|
||||
switcher.change("test_layout");
|
||||
}
|
||||
|
||||
private function onFrameSwitch(frame:IView<Dynamic>):Void {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
style: background
|
||||
geometry.stretch: true
|
||||
views:
|
||||
- $type: haxework.view.ImageView
|
||||
geometry.padding: 10
|
||||
|
||||
@@ -9,6 +9,7 @@ import haxework.view.skin.Skin;
|
||||
private function colorViewFactory(index:Int, color:Int) {
|
||||
var view = new ButtonView();
|
||||
view.setSize(48, 48, "fixed");
|
||||
view.geometry.padding = 0;
|
||||
view.skin = Skin.buttonColor(color);
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -7,21 +7,24 @@ views:
|
||||
layout.margin: 10
|
||||
layout.vAlign: middle
|
||||
skin:
|
||||
$type: haxework.view.skin.ColorSkin
|
||||
color: 0xffff00
|
||||
$type: haxework.view.skin.SpriteSkin
|
||||
background.color: 0xffff00
|
||||
background.alpha: 1
|
||||
views:
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.width: 100
|
||||
geometry.height: 100
|
||||
skin:
|
||||
$type: haxework.view.skin.ColorSkin
|
||||
color: 0xff0000
|
||||
$type: haxework.view.skin.SpriteSkin
|
||||
background.color: 0xff0000
|
||||
background.alpha: 1
|
||||
- $type: haxework.view.group.VGroupView
|
||||
geometry.padding: 10
|
||||
layout.margin: 10
|
||||
skin:
|
||||
$type: haxework.view.skin.ColorSkin
|
||||
color: 0x00ffff
|
||||
$type: haxework.view.skin.SpriteSkin
|
||||
background.color: 0x00ffff
|
||||
background.alpha: 1
|
||||
views:
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.width: 100
|
||||
@@ -29,31 +32,30 @@ views:
|
||||
size:
|
||||
_test_: [200, 200]
|
||||
skin:
|
||||
$type: haxework.view.skin.ColorSkin
|
||||
color: 0xff0000
|
||||
$type: haxework.view.skin.SpriteSkin
|
||||
background.color: 0xff0000
|
||||
background.alpha: 1
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.width: 100
|
||||
geometry.height: 100
|
||||
skin:
|
||||
$type: haxework.view.skin.ColorSkin
|
||||
color: 0xff0000
|
||||
- $type: haxework.view.list.VListView
|
||||
factory: ~haxework.view.list.LabelListItem.factory
|
||||
geometry.width: 100
|
||||
geometry.height: 100
|
||||
scroll:
|
||||
$type: haxework.view.list.VScrollBarView
|
||||
data:
|
||||
- "aaa"
|
||||
$type: haxework.view.skin.SpriteSkin
|
||||
background.color: 0xff0000
|
||||
background.alpha: 1
|
||||
- $type: haxework.view.text.TextView
|
||||
geometry.padding: 20
|
||||
text: "Azazaza"
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.width: 60%
|
||||
geometry.height: 100%
|
||||
skin:
|
||||
$type: haxework.view.skin.ColorSkin
|
||||
color: 0xff0000
|
||||
$type: haxework.view.skin.SpriteSkin
|
||||
background.color: 0xff0000
|
||||
background.alpha: 1
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.width: 40%
|
||||
geometry.height: 80%
|
||||
skin:
|
||||
$type: haxework.view.skin.ColorSkin
|
||||
color: 0xff0000
|
||||
$type: haxework.view.skin.SpriteSkin
|
||||
background.color: 0xff0000
|
||||
background.alpha: 1
|
||||
|
||||
@@ -3,13 +3,14 @@ package haxework.view;
|
||||
import flash.display.DisplayObject;
|
||||
import flash.geom.Rectangle;
|
||||
import haxework.view.geometry.Geometry;
|
||||
import haxework.view.geometry.Size;
|
||||
import haxework.view.group.IGroupView;
|
||||
import haxework.view.skin.ISkin;
|
||||
import haxework.view.theme.StyleId;
|
||||
|
||||
interface IView<C:DisplayObject> {
|
||||
@:style public var geometry(default, default):Geometry;
|
||||
@:style public var skin(default, default):ISkin<Dynamic>;
|
||||
@:style public var skin(default, set):ISkin<Dynamic>;
|
||||
|
||||
public var id(default, default):String;
|
||||
|
||||
@@ -19,7 +20,9 @@ interface IView<C:DisplayObject> {
|
||||
public var width(default, null):Float;
|
||||
public var height(default, null):Float;
|
||||
|
||||
public var style(default, default):StyleId;
|
||||
public var size(default, null):Size;
|
||||
|
||||
public var style(default, set):StyleId;
|
||||
|
||||
public var content(default, null):C;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ class ImageView extends SpriteView {
|
||||
public function new(image:BitmapData = null) {
|
||||
super();
|
||||
fillType = FillType.DEFAULT;
|
||||
skin = bitmapSkin;
|
||||
if (image != null) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package haxework.view;
|
||||
|
||||
import haxework.view.skin.ColorSkin;
|
||||
import flash.display.Sprite;
|
||||
import haxework.view.skin.Skin;
|
||||
|
||||
class SpriteView extends View<Sprite> {
|
||||
|
||||
public function new() {
|
||||
super(new Sprite());
|
||||
skin = new ColorSkin(0, 0);
|
||||
skin = Skin.transparent;
|
||||
}
|
||||
|
||||
override public function redraw():Void {
|
||||
this.content.graphics.clear();
|
||||
this.content.graphics.clear(); // ToDo: in skin
|
||||
super.redraw();
|
||||
#if dev_layout
|
||||
var graphics = content.graphics;
|
||||
|
||||
@@ -4,6 +4,7 @@ import flash.display.DisplayObject;
|
||||
import flash.display.InteractiveObject;
|
||||
import flash.geom.Rectangle;
|
||||
import haxework.view.geometry.Geometry;
|
||||
import haxework.view.geometry.Size;
|
||||
import haxework.view.geometry.SizeSet;
|
||||
import haxework.view.group.IGroupView;
|
||||
import haxework.view.skin.ISkin;
|
||||
@@ -18,8 +19,8 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
@:provide var theme:ITheme;
|
||||
|
||||
public var geometry(default, default):Geometry;
|
||||
public var skin(default, default):ISkin<Dynamic>;
|
||||
public var style(default, default):StyleId;
|
||||
public var skin(default, set):ISkin<Dynamic>;
|
||||
public var style(default, set):StyleId;
|
||||
|
||||
public var id(default, default):String;
|
||||
|
||||
@@ -29,6 +30,8 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
public var width(default, null):Float;
|
||||
public var height(default, null):Float;
|
||||
|
||||
public var size(default, null):Size;
|
||||
|
||||
public var content(default, null):C;
|
||||
|
||||
public var parent(default, null):Null<IGroupView>;
|
||||
@@ -39,11 +42,12 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
|
||||
public var rect(get, null):Rectangle;
|
||||
|
||||
private var size:SizeSet;
|
||||
private var sizeSet:SizeSet;
|
||||
|
||||
public function new(content:C) {
|
||||
id = Type.getClassName(Type.getClass(this)) + counter++;
|
||||
size = new SizeSet();
|
||||
sizeSet = new SizeSet();
|
||||
size = 0;
|
||||
this.content = content;
|
||||
x = 0;
|
||||
y = 0;
|
||||
@@ -80,10 +84,13 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
}
|
||||
|
||||
public function setSize(width:Float, height:Float, type:String = "default"):Void {
|
||||
if (size.update([width, height], type)) {
|
||||
var s = size.toSize();
|
||||
this.width = s.width;
|
||||
this.height = s.height;
|
||||
if (sizeSet.update([width, height], type)) {
|
||||
var s = sizeSet.toSize();
|
||||
this.width = s.width + geometry.padding.horizontal;
|
||||
this.height = s.height + geometry.padding.vertical;
|
||||
size = sizeSet.toSize(false);
|
||||
size.width += geometry.padding.horizontal;
|
||||
size.height += geometry.padding.vertical;
|
||||
toUpdateParent();
|
||||
toRedraw();
|
||||
}
|
||||
@@ -113,6 +120,16 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
return this.skin;
|
||||
}
|
||||
|
||||
private function set_style(value:StyleId):StyleId {
|
||||
if (value != null && style != value) {
|
||||
style = value;
|
||||
if (theme != null) {
|
||||
theme.bind(style, this);
|
||||
}
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
private function set_visible(value:Bool):Bool {
|
||||
if (visible != value) {
|
||||
visible = value;
|
||||
|
||||
@@ -65,6 +65,10 @@ abstract Box(Array<Float>) {
|
||||
}
|
||||
}
|
||||
|
||||
public function clone():Box {
|
||||
return new Box(this);
|
||||
}
|
||||
|
||||
@:from static public inline function fromArray(value:Array<Float>):Box {
|
||||
return new Box(value);
|
||||
}
|
||||
|
||||
@@ -17,12 +17,15 @@ class SizeSet extends StringMap<Size> {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function toSize():Size {
|
||||
public function toSize(percent:Bool = true):Size {
|
||||
var result:Size = 0;
|
||||
for (value in iterator()) {
|
||||
for (type in keys()) {
|
||||
if (percent || type.indexOf("percent") == -1) {
|
||||
var value = get(type);
|
||||
result.width = Math.max(result.width, value.width);
|
||||
result.height = Math.max(result.height, value.height);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ class DefaultLayout extends Layout {
|
||||
setViewHeight(group, view);
|
||||
placeViewHorizontal(group, view);
|
||||
placeViewVertical(group, view);
|
||||
width = Math.max(width, view.width + view.geometry.margin.horizontal);
|
||||
height = Math.max(height, view.height + view.geometry.margin.horizontal);
|
||||
width = Math.max(width, view.size.width + view.geometry.margin.horizontal);
|
||||
height = Math.max(height, view.size.height + view.geometry.margin.horizontal);
|
||||
}
|
||||
if (!overflow) group.setSize(width, height, "group");
|
||||
}
|
||||
@@ -38,11 +38,11 @@ class DefaultLayout extends Layout {
|
||||
}
|
||||
|
||||
private function setViewWidth(group:IGroupView, view:IView<Dynamic>):Void {
|
||||
view.setSize(view.geometry.width.percent / 100 * (group.width - view.geometry.margin.horizontal - group.geometry.padding.horizontal), 0, "percent.width");
|
||||
view.setSize(view.geometry.width.percent / 100 * (group.width - view.geometry.margin.horizontal - group.geometry.padding.horizontal) - view.geometry.padding.horizontal, 0, "percent.width");
|
||||
}
|
||||
|
||||
private function setViewHeight(group:IGroupView, view:IView<Dynamic>):Void {
|
||||
view.setSize(0, view.geometry.height.percent / 100 * (group.height - view.geometry.margin.vertical - group.geometry.padding.vertical), "percent.height");
|
||||
view.setSize(0, view.geometry.height.percent / 100 * (group.height - view.geometry.margin.vertical - group.geometry.padding.vertical) - view.geometry.padding.vertical, "percent.height");
|
||||
}
|
||||
|
||||
private function placeViewHorizontal(group:IGroupView, view:IView<Dynamic>):Void {
|
||||
|
||||
@@ -10,21 +10,19 @@ class HorizontalLayout extends DefaultLayout {
|
||||
override public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void {
|
||||
views = filterViews(group, views);
|
||||
|
||||
var fixedSize:Float = group.geometry.padding.horizontal + margin * (views.length - 1);
|
||||
var leftSize:Float = group.width;
|
||||
var fixedSize:Float = margin * (views.length - 1);
|
||||
var leftSize:Float = group.width - group.geometry.padding.horizontal;
|
||||
|
||||
var maxSize:Float = group.geometry.padding.vertical;
|
||||
var maxSize:Float = 0;
|
||||
|
||||
for (view in views) {
|
||||
setViewHeight(group, view);
|
||||
placeViewVertical(group, view);
|
||||
switch view.geometry.width.type {
|
||||
case PERCENT:
|
||||
leftSize -= (view.geometry.margin.horizontal);
|
||||
case FIXED:
|
||||
fixedSize += (view.width + view.geometry.margin.horizontal);
|
||||
}
|
||||
maxSize = Math.max(maxSize, view.height + view.geometry.margin.vertical + group.geometry.padding.vertical);
|
||||
maxSize = Math.max(maxSize, view.size.height + view.geometry.margin.vertical);
|
||||
}
|
||||
|
||||
if (!overflow) group.setSize(fixedSize, maxSize, "group");
|
||||
@@ -35,7 +33,7 @@ class HorizontalLayout extends DefaultLayout {
|
||||
case PERCENT:
|
||||
var result = view.geometry.width.value / 100 * leftSize;
|
||||
fixedSize += result + view.geometry.margin.horizontal;
|
||||
view.setSize(result, 0, "percent.width");
|
||||
view.setSize(result - view.geometry.padding.horizontal, 0, "percent.width");
|
||||
case _:
|
||||
};
|
||||
}
|
||||
@@ -50,6 +48,8 @@ class HorizontalLayout extends DefaultLayout {
|
||||
for (view in views) {
|
||||
view.x = x + view.geometry.margin.left;
|
||||
x += (view.width + view.geometry.margin.horizontal + margin);
|
||||
setViewHeight(group, view);
|
||||
placeViewVertical(group, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,21 +10,19 @@ class VerticalLayout extends DefaultLayout {
|
||||
override public function place(group:IGroupView, views:Array<IView<Dynamic>>):Void {
|
||||
views = filterViews(group, views);
|
||||
|
||||
var fixedSize:Float = group.geometry.padding.vertical + margin * (views.length - 1);
|
||||
var leftSize:Float = group.height;
|
||||
var fixedSize:Float = margin * (views.length - 1);
|
||||
var leftSize:Float = group.height - group.geometry.padding.vertical;
|
||||
|
||||
var maxSize:Float = group.geometry.padding.horizontal;
|
||||
var maxSize:Float = 0;
|
||||
|
||||
for (view in views) {
|
||||
setViewWidth(group, view);
|
||||
placeViewHorizontal(group, view);
|
||||
switch view.geometry.height.type {
|
||||
case PERCENT:
|
||||
leftSize -= (view.geometry.margin.vertical);
|
||||
case FIXED:
|
||||
fixedSize += (Math.max(view.geometry.height.value, view.height) + view.geometry.margin.vertical);
|
||||
}
|
||||
maxSize = Math.max(maxSize, view.width + view.geometry.margin.horizontal + group.geometry.padding.horizontal);
|
||||
maxSize = Math.max(maxSize, view.size.width + view.geometry.margin.horizontal);
|
||||
}
|
||||
|
||||
if (!overflow) group.setSize(maxSize, fixedSize, "group");
|
||||
@@ -35,7 +33,7 @@ class VerticalLayout extends DefaultLayout {
|
||||
case PERCENT:
|
||||
var result = view.geometry.height.value / 100 * leftSize;
|
||||
fixedSize += result + view.geometry.margin.vertical;
|
||||
view.setSize(0, result, "percent.height");
|
||||
view.setSize(0, result - view.geometry.padding.vertical, "percent.height");
|
||||
case _:
|
||||
};
|
||||
}
|
||||
@@ -50,6 +48,8 @@ class VerticalLayout extends DefaultLayout {
|
||||
for (view in views) {
|
||||
view.y = y + view.geometry.margin.top;
|
||||
y += (view.height + view.geometry.margin.vertical + margin);
|
||||
setViewWidth(group, view);
|
||||
placeViewHorizontal(group, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package haxework.view.skin;
|
||||
|
||||
class BorderSkin implements ISkin<SpriteView> {
|
||||
|
||||
public var color(default, default):Int;
|
||||
public var alpha(default, default):Float;
|
||||
public var tickness(default, default):Float;
|
||||
|
||||
public function new(color:Int = 0xffffff, alpha:Float = 1.0, tickness: Float = 1.0) {
|
||||
this.color = color;
|
||||
this.alpha = alpha;
|
||||
this.tickness = tickness;
|
||||
}
|
||||
|
||||
public function draw(view:SpriteView):Void {
|
||||
view.content.graphics.lineStyle(tickness, color, alpha, true);
|
||||
view.content.graphics.drawRect(tickness / 2, tickness / 2, view.width - tickness, view.height - tickness);
|
||||
view.content.graphics.lineStyle();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package haxework.view.skin;
|
||||
|
||||
class ColorSkin implements ISkin<SpriteView> {
|
||||
|
||||
public var color(default, default):Int;
|
||||
public var alpha(default, default):Float;
|
||||
|
||||
public function new(color:Int = 0xffffff, alpha:Float = 1.0) {
|
||||
this.color = color;
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
public function draw(view:SpriteView):Void {
|
||||
view.content.graphics.beginFill(color, alpha);
|
||||
view.content.graphics.drawRect(0, 0, view.width, view.height);
|
||||
view.content.graphics.endFill();
|
||||
}
|
||||
}
|
||||
@@ -6,18 +6,14 @@ import haxework.view.utils.DrawUtil;
|
||||
|
||||
class Skin {
|
||||
|
||||
public static var transparent(default, never):ISkin<SpriteView> = new ColorSkin(0, 0);
|
||||
public static var transparent(default, never):ISkin<SpriteView> = new SpriteSkin({color: 0, alpha: 0});
|
||||
|
||||
public static function bitmap(image:BitmapData, fillType:FillType = null):ISkin<SpriteView> {
|
||||
return new BitmapSkin(image, fillType);
|
||||
}
|
||||
|
||||
public static function color(color:Int, alpha:Float = 1.0):ISkin<SpriteView> {
|
||||
return new ColorSkin(color, alpha);
|
||||
}
|
||||
|
||||
public static function border(color:Int, alpha:Float = 1.0, tickness:Float = 1.0):ISkin<SpriteView> {
|
||||
return new BorderSkin(color, alpha, tickness);
|
||||
return new SpriteSkin({color: color, alpha: alpha});
|
||||
}
|
||||
|
||||
public static function buttonColor(color:Int, borderColor:Int = -1):ISkin<ButtonView> {
|
||||
|
||||
55
src/main/haxework/view/skin/SpriteSkin.hx
Normal file
55
src/main/haxework/view/skin/SpriteSkin.hx
Normal file
@@ -0,0 +1,55 @@
|
||||
package haxework.view.skin;
|
||||
|
||||
import flash.display.Graphics;
|
||||
import haxework.color.Color;
|
||||
|
||||
typedef Border = {
|
||||
@:optional var color:Color;
|
||||
@:optional var thickness:Float;
|
||||
@:optional var alpha:Float;
|
||||
}
|
||||
|
||||
typedef Background = {
|
||||
@:optional var color:Color;
|
||||
@:optional var alpha:Float;
|
||||
}
|
||||
|
||||
class SpriteSkin implements ISkin<SpriteView> {
|
||||
|
||||
public var border(default, default):Border;
|
||||
public var background(default, default):Background;
|
||||
|
||||
public function new(?background:Background, ?border:Border) {
|
||||
this.background = resolveBackground(background);
|
||||
this.border = resolveBorder(border);
|
||||
}
|
||||
|
||||
private static function resolveBackground(value:Background):Background {
|
||||
return value != null ? {
|
||||
color: value.color != null ? value.color : 0x000000,
|
||||
alpha: value.alpha != null ? value.alpha : 1.0
|
||||
} : {};
|
||||
}
|
||||
|
||||
private static function resolveBorder(value:Border):Border {
|
||||
return value != null ? {
|
||||
color: value.color != null ? value.color : 0x000000,
|
||||
alpha: value.alpha != null ? value.alpha : 1.0,
|
||||
thickness: value.thickness != null ? value.thickness : 1
|
||||
} : {};
|
||||
}
|
||||
|
||||
public function draw(view:SpriteView):Void {
|
||||
var graphics:Graphics = view.content.graphics;
|
||||
graphics.clear();
|
||||
if (border.color != null) {
|
||||
graphics.lineStyle(border.thickness, border.color, border.alpha, true);
|
||||
}
|
||||
if (background.color != null) {
|
||||
graphics.beginFill(background.color, background.alpha);
|
||||
}
|
||||
graphics.drawRect(0, 0, view.width, view.height);
|
||||
graphics.lineStyle();
|
||||
graphics.endFill();
|
||||
}
|
||||
}
|
||||
23
src/main/haxework/view/text/FontPreset.hx
Normal file
23
src/main/haxework/view/text/FontPreset.hx
Normal file
@@ -0,0 +1,23 @@
|
||||
package haxework.view.text;
|
||||
|
||||
import haxework.color.Color;
|
||||
import flash.text.TextFormatAlign;
|
||||
|
||||
class FontPreset {
|
||||
public var family(default, default):String;
|
||||
public var embed(default, default):Bool;
|
||||
public var color(default, default):Color;
|
||||
public var size(default, default):Int;
|
||||
public var bold(default, default):Bool;
|
||||
public var align(default, default):TextFormatAlign;
|
||||
|
||||
public function new(family:String = null, embed:Bool = false, color:Color = null, size:Int = 16,
|
||||
bold:Bool = false, align:TextFormatAlign = null) {
|
||||
this.family = family;
|
||||
this.embed = embed;
|
||||
this.color = color != null ? color : 0xffffff;
|
||||
this.size = size;
|
||||
this.bold = bold;
|
||||
this.align = align;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package haxework.view.text;
|
||||
|
||||
import flash.text.TextFormatAlign;
|
||||
|
||||
class FontStyle {
|
||||
public var family(default, default):String;
|
||||
public var embed(default, default):Bool;
|
||||
public var color(default, default):Int;
|
||||
public var size(default, default):Int;
|
||||
public var bold(default, default):Bool;
|
||||
public var align(default, default):TextFormatAlign;
|
||||
|
||||
public function new() {
|
||||
family = null;
|
||||
embed = false;
|
||||
color = 0xffffff;
|
||||
size = 16;
|
||||
bold = false;
|
||||
align = null;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import haxework.view.IView;
|
||||
import haxework.view.layout.ILayout;
|
||||
|
||||
interface ITextView extends IView<Dynamic> {
|
||||
@:style public var font(default, default):FontStyle;
|
||||
@:style public var font(default, default):FontPreset;
|
||||
@:style public var layout(default, default):ILayout;
|
||||
|
||||
public var textField(default, null):TextField;
|
||||
|
||||
@@ -12,7 +12,7 @@ import haxework.view.layout.ILayout;
|
||||
import haxework.view.layout.Layout;
|
||||
|
||||
class TextView extends SpriteView implements ITextView {
|
||||
public var font(default, default):FontStyle;
|
||||
public var font(default, default):FontPreset;
|
||||
public var layout(default, default):ILayout;
|
||||
|
||||
public var textField(default, null):TextField;
|
||||
@@ -27,7 +27,7 @@ class TextView extends SpriteView implements ITextView {
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
font = new FontStyle();
|
||||
font = new FontPreset();
|
||||
style = "text";
|
||||
layout = new Layout();
|
||||
textField = buildTextField();
|
||||
|
||||
18
src/main/haxework/view/theme/FontStyle.hx
Normal file
18
src/main/haxework/view/theme/FontStyle.hx
Normal file
@@ -0,0 +1,18 @@
|
||||
package haxework.view.theme;
|
||||
|
||||
import haxework.view.text.ITextView;
|
||||
import haxework.view.text.FontPreset;
|
||||
|
||||
class FontStyle implements IStyle<ITextView> {
|
||||
|
||||
private var font:FontPreset;
|
||||
|
||||
public function new(font:FontPreset) {
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
public function apply(view:ITextView):Void {
|
||||
view.font = font;
|
||||
view.toUpdate();
|
||||
}
|
||||
}
|
||||
23
src/main/haxework/view/theme/GeometryStyle.hx
Normal file
23
src/main/haxework/view/theme/GeometryStyle.hx
Normal file
@@ -0,0 +1,23 @@
|
||||
package haxework.view.theme;
|
||||
|
||||
import haxework.view.geometry.Geometry;
|
||||
|
||||
class GeometryStyle implements IStyle<IView<Dynamic>> {
|
||||
|
||||
private var geometry:Geometry;
|
||||
|
||||
public function new(geometry:Geometry) {
|
||||
this.geometry = geometry;
|
||||
}
|
||||
|
||||
public function apply(view:IView<Dynamic>):Void {
|
||||
var update = false;
|
||||
if (!geometry.padding.empty) {
|
||||
view.geometry.padding = geometry.padding.clone();
|
||||
update = true;
|
||||
}
|
||||
if (update) {
|
||||
view.toUpdateParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/main/haxework/view/theme/IStyle.hx
Normal file
5
src/main/haxework/view/theme/IStyle.hx
Normal file
@@ -0,0 +1,5 @@
|
||||
package haxework.view.theme;
|
||||
|
||||
interface IStyle<V:IView<Dynamic>> {
|
||||
public function apply(view:V):Void;
|
||||
}
|
||||
@@ -18,6 +18,5 @@ typedef ThemeColors = {
|
||||
interface ITheme {
|
||||
public var font(default, set):ThemeFont;
|
||||
public var colors(default, set):ThemeColors;
|
||||
|
||||
public function bind(styles:Array<String>, view:IView<Dynamic>):Void;
|
||||
public function bind(style:StyleId, view:IView<Dynamic>):Void;
|
||||
}
|
||||
|
||||
18
src/main/haxework/view/theme/LayoutStyle.hx
Normal file
18
src/main/haxework/view/theme/LayoutStyle.hx
Normal file
@@ -0,0 +1,18 @@
|
||||
package haxework.view.theme;
|
||||
|
||||
import haxework.view.group.IGroupView;
|
||||
import haxework.view.layout.ILayout;
|
||||
|
||||
class LayoutStyle implements IStyle<IGroupView> {
|
||||
|
||||
private var layout:ILayout;
|
||||
|
||||
public function new(layout:ILayout) {
|
||||
this.layout = layout;
|
||||
}
|
||||
|
||||
public function apply(view:IGroupView):Void {
|
||||
view.layout = layout;
|
||||
view.toUpdate();
|
||||
}
|
||||
}
|
||||
17
src/main/haxework/view/theme/SkinStyle.hx
Normal file
17
src/main/haxework/view/theme/SkinStyle.hx
Normal file
@@ -0,0 +1,17 @@
|
||||
package haxework.view.theme;
|
||||
|
||||
import haxework.view.skin.ISkin;
|
||||
|
||||
class SkinStyle implements IStyle<IView<Dynamic>> {
|
||||
|
||||
private var skin:ISkin<Dynamic>;
|
||||
|
||||
public function new(skin:ISkin<Dynamic>) {
|
||||
this.skin = skin;
|
||||
}
|
||||
|
||||
public function apply(view:IView<Dynamic>):Void {
|
||||
view.skin = skin;
|
||||
view.toRedraw();
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package haxework.view.theme;
|
||||
abstract StyleId(Array<String>) {
|
||||
|
||||
public function new(value:Array<String>) {
|
||||
this = value;
|
||||
this = value != null ? value : [];
|
||||
}
|
||||
|
||||
@:to public inline function toArray():Array<String> {
|
||||
|
||||
@@ -2,11 +2,57 @@ package haxework.view.theme;
|
||||
|
||||
import flash.text.Font;
|
||||
import flash.text.FontType;
|
||||
import haxe.ds.StringMap;
|
||||
import haxework.color.Color;
|
||||
import haxework.view.geometry.Geometry;
|
||||
import haxework.view.skin.Skin;
|
||||
import haxework.view.skin.SpriteSkin;
|
||||
import haxework.view.text.FontPreset;
|
||||
import haxework.view.theme.ITheme;
|
||||
|
||||
using haxework.color.ColorUtil;
|
||||
|
||||
typedef StyleSet = Array<IStyle<Dynamic>>;
|
||||
|
||||
class StyleMap extends StringMap<StyleSet> {
|
||||
|
||||
private var views:Map<IView<Dynamic>, String> = new Map();
|
||||
private var viewsByStyle:Map<String, Array<IView<Dynamic>>> = new Map();
|
||||
|
||||
private function apply(styles:StyleSet, view:IView<Dynamic>):Void {
|
||||
for (item in styles) {
|
||||
item.apply(view);
|
||||
}
|
||||
}
|
||||
|
||||
public function put(key:String, value:StyleSet):Void {
|
||||
set(key, value);
|
||||
if (viewsByStyle.exists(key)) {
|
||||
for (view in viewsByStyle.get(key)) {
|
||||
apply(value, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function connect(key:String, view:IView<Dynamic>):Void {
|
||||
disconnect(view);
|
||||
if (!viewsByStyle.exists(key)) {
|
||||
viewsByStyle.set(key, []);
|
||||
}
|
||||
viewsByStyle.get(key).push(view);
|
||||
if (exists(key)) {
|
||||
apply(get(key), view);
|
||||
}
|
||||
}
|
||||
|
||||
public function disconnect(view:IView<Dynamic>):Void {
|
||||
if (views.exists(view)) {
|
||||
viewsByStyle.get(views.get(view)).remove(view);
|
||||
views.remove(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Theme implements ITheme {
|
||||
// ToDo: configurable
|
||||
public var baseFontSize = 18;
|
||||
@@ -16,7 +62,10 @@ class Theme implements ITheme {
|
||||
public var font(default, set):ThemeFont;
|
||||
public var colors(default, set):ThemeColors;
|
||||
|
||||
private var styles:StyleMap;
|
||||
|
||||
public function new(?font:ThemeFont, ?colors:ThemeColors) {
|
||||
styles = new StyleMap();
|
||||
this.font = font;
|
||||
this.colors = colors;
|
||||
L.d("Theme", 'font: ${this.font}');
|
||||
@@ -39,12 +88,74 @@ class Theme implements ITheme {
|
||||
return colors;
|
||||
}
|
||||
|
||||
private function reload():Void {
|
||||
|
||||
private function reload():Void {
|
||||
styles.put("background", background());
|
||||
styles.put("border", background(null, true));
|
||||
styles.put("frame", background(null, true).concat([new GeometryStyle(new Geometry().setPadding(2))]));
|
||||
|
||||
styles.put("text", text());
|
||||
styles.put("label", text().concat([new GeometryStyle(new Geometry().setPadding([8, 2]))]));
|
||||
styles.put("button", button());
|
||||
styles.put("dropdown", background(null, true));
|
||||
styles.put("tab", text().concat([
|
||||
new SkinStyle(Skin.tabColor(this.colors.light)),
|
||||
new GeometryStyle(new Geometry().setPadding([25, 8]))
|
||||
]));
|
||||
|
||||
styles.put("text0", text().concat(background(this.colors.light.diff(-16))));
|
||||
styles.put("text1", text().concat(background(this.colors.light.diff(16))));
|
||||
styles.put("scroll.vertical", [
|
||||
new SkinStyle(Skin.scrollVertical(this.colors.light, this.colors.dark)),
|
||||
]);
|
||||
styles.put("scroll.horizontal", [
|
||||
new SkinStyle(Skin.scrollHorizontal(this.colors.light, this.colors.dark)),
|
||||
]);
|
||||
}
|
||||
|
||||
public function bind(styles:Array<String>, view:IView<Dynamic>):Void {
|
||||
//data.bind(id, view, "skin");
|
||||
public function background(?color:Color, border:Bool = false):StyleSet {
|
||||
if (color == null) {
|
||||
color = colors.dark;
|
||||
}
|
||||
return [
|
||||
new SkinStyle(new SpriteSkin(
|
||||
{color: color},
|
||||
border ? {color: colors.light, thickness: 2} : null
|
||||
)),
|
||||
];
|
||||
}
|
||||
|
||||
public function text(?color:Color):StyleSet {
|
||||
if (color == null) {
|
||||
color = colors.text;
|
||||
}
|
||||
return [
|
||||
new FontStyle(new FontPreset(font.name, font.embed, color, baseFontSize)),
|
||||
];
|
||||
}
|
||||
|
||||
public function button(?color:Color, ?textColor:Color):StyleSet {
|
||||
if (color == null) {
|
||||
color = colors.light;
|
||||
}
|
||||
return text(textColor).concat([
|
||||
new SkinStyle(Skin.buttonColor(color)),
|
||||
new GeometryStyle(new Geometry().setPadding([25, 8])),
|
||||
]);
|
||||
}
|
||||
|
||||
public function textBox(?color:Color):StyleSet {
|
||||
return text(color).concat([
|
||||
new SkinStyle(new SpriteSkin({color: 0, alpha: 0.1}, {color: colors.light, thickness: 2})),
|
||||
]);
|
||||
}
|
||||
|
||||
public function bind(style:StyleId, view:IView<Dynamic>):Void {
|
||||
styles.connect(style, view);
|
||||
}
|
||||
|
||||
public function unbind(view:IView<Dynamic>):Void {
|
||||
styles.disconnect(view);
|
||||
}
|
||||
|
||||
private static function resolveFont(font:ThemeFont):ThemeFont {
|
||||
|
||||
Reference in New Issue
Block a user