From 215d820e68d240b5a0ed6c6ac13cf8969a20d8fd Mon Sep 17 00:00:00 2001 From: shmyga Date: Tue, 9 Jul 2019 17:44:48 +0300 Subject: [PATCH] [view] add Theme --- demo/src/demo/AppTheme.hx | 35 +++++++++ demo/src/demo/Demo.hx | 10 +-- demo/src/demo/Theme.hx | 40 ---------- demo/src/demo/form/SelectForm.yaml | 15 ++-- src/main/haxework/App.hx | 5 +- src/main/haxework/resources/IResources.hx | 2 - src/main/haxework/resources/Resources.hx | 3 - src/main/haxework/view/SelectView.hx | 3 + src/main/haxework/view/View.hx | 7 +- src/main/haxework/view/theme/ITheme.hx | 29 +++++++ src/main/haxework/view/theme/Theme.hx | 95 +++++++++++++++++++++++ 11 files changed, 185 insertions(+), 59 deletions(-) create mode 100644 demo/src/demo/AppTheme.hx delete mode 100644 demo/src/demo/Theme.hx create mode 100644 src/main/haxework/view/theme/ITheme.hx create mode 100644 src/main/haxework/view/theme/Theme.hx diff --git a/demo/src/demo/AppTheme.hx b/demo/src/demo/AppTheme.hx new file mode 100644 index 0000000..7f5df4c --- /dev/null +++ b/demo/src/demo/AppTheme.hx @@ -0,0 +1,35 @@ +package demo; + +import haxework.color.Color; +import haxework.view.core.Geometry; +import haxework.view.skin.Skin; +import haxework.view.theme.Theme; + +using haxework.color.ColorUtil; + +class AppTheme extends Theme { + + public function new(?color:Color, ?textColor:Color):Void { + super({name: "Courirer"}, {light: color, text: textColor}); + var background = Skin.color(0x000000); + var border = Skin.border(colors.light.multiply(1.5), 1, 2); + data.set("text0", [ + Skin.color(colors.light.diff(128)), + text(colors.light.diff(-128)), + ]); + data.set("text1", [ + Skin.color(colors.light.diff(64)), + text(colors.light.diff(-128)), + ]); + data.set("text", data.get("text0")); + data.set("background", [background]); + data.set("button", [Skin.buttonColor(colors.light), text(colors.text)]); + data.set("tab", [Skin.tabColor(colors.light), text(colors.text), Skin.geometry(new Geometry().setPadding([25, 8]))]); + data.set("view", [Skin.color(colors.light), border, text(colors.text)]); + data.set("scroll", [Skin.scrollVertical(colors.light, colors.light.diff(128))]); + data.set("border", [border]); + data.set("panel", [background, border]); + + data.set("test", [Skin.color(0x00ffff)]); + } +} diff --git a/demo/src/demo/Demo.hx b/demo/src/demo/Demo.hx index 285f2f1..a5feb94 100644 --- a/demo/src/demo/Demo.hx +++ b/demo/src/demo/Demo.hx @@ -24,10 +24,11 @@ import haxework.log.TraceLogger; } private function choiceColor():Void { - new ColorPopup() + // ToDo: update Theme + /*new ColorPopup() .show() - .then(function(color) Theme.setColor(color)) - .catchError(function(e) {}); + .then(function(color) AppTheme.setColor(color)) + .catchError(function(e) {});*/ } } @@ -36,9 +37,8 @@ class Demo extends App implements DemoListener { public static function main() { L.push(new TraceLogger()); - var app = new Demo(); + var app = new Demo(new AppTheme()); app.resources.image.put("logo", HaxeLogo.resolve()); - Theme.setColor(0x33aa33); app.start(new DemoView()); var dispatcher = new DemoDispatcher(); diff --git a/demo/src/demo/Theme.hx b/demo/src/demo/Theme.hx deleted file mode 100644 index cc53ecf..0000000 --- a/demo/src/demo/Theme.hx +++ /dev/null @@ -1,40 +0,0 @@ -package demo; - -import haxework.color.Color; -import haxework.resources.IResources; -import haxework.view.core.Geometry; -import haxework.view.skin.Skin; -import haxework.view.skin.TextSkin; -using haxework.color.ColorUtil; - -class Theme { - - @:provide static var resources:IResources; - - public static function setColor(color:Color, ?textColor:Color):Void { - if (textColor == null) { - textColor = 0xffffff; - } - var text = new TextSkin(textColor, 16, "Courirer"); - var background = Skin.color(0x000000); - var border = Skin.border(color.multiply(1.5), 1, 2); - resources.skin.put("text0", [ - Skin.color(color.diff(128)), - new TextSkin(color.diff(-128), 16, "Courirer"), - ]); - resources.skin.put("text1", [ - Skin.color(color.diff(64)), - new TextSkin(color.diff(-128), 16, "Courirer"), - ]); - resources.skin.put("text", resources.skin.get("text0")); - resources.skin.put("background", [background]); - resources.skin.put("button", [Skin.buttonColor(color), text]); - resources.skin.put("tab", [Skin.tabColor(color), text, Skin.geometry(new Geometry().setPadding([25, 8]))]); - resources.skin.put("view", [Skin.color(color), border, text]); - resources.skin.put("scroll", [Skin.scrollVertical(color, color.diff(128))]); - resources.skin.put("border", [border]); - resources.skin.put("panel", [background, border]); - - resources.skin.put("test", [Skin.color(0x00ffff)]); - } -} diff --git a/demo/src/demo/form/SelectForm.yaml b/demo/src/demo/form/SelectForm.yaml index 9dd6bf9..2cedf95 100644 --- a/demo/src/demo/form/SelectForm.yaml +++ b/demo/src/demo/form/SelectForm.yaml @@ -18,11 +18,16 @@ views: layout.margin: 2 dataView.layout.margin: 1 labelSkinId: text - labelBuilder: ~function(item) return item.label + labelBuilder: | + ~function(item:{id:Int,label:String}):String { + var result = item.label; + result += " (" + item.id + ")"; + return result; + } data: - - {id: 1, label: "item 1", $type: Dynamic} - - {id: 2, label: "item 2", $type: Dynamic} - - {id: 3, label: "item 3", $type: Dynamic} - - {id: 4, label: "item 4", $type: Dynamic} + - {id: 1, label: "Aaaaaaaa", $type: Dynamic} + - {id: 2, label: "Bbbbbb", $type: Dynamic} + - {id: 3, label: "Cccc", $type: Dynamic} + - {id: 4, label: "Ddd", $type: Dynamic} selectedId: 1 +onSelect: ~function(value) trace('select', value) diff --git a/src/main/haxework/App.hx b/src/main/haxework/App.hx index f9cab74..7e866da 100644 --- a/src/main/haxework/App.hx +++ b/src/main/haxework/App.hx @@ -11,15 +11,18 @@ import haxework.resources.Resources; import haxework.view.IView; import haxework.view.popup.PopupManager; import haxework.view.Root; +import haxework.view.theme.ITheme; class App { @:provide var app:App; + @:provide var theme:ITheme; @:provide var resources:IResources; @:provide var loaderManager:ILoaderManager; @:provide var popupManager:PopupManager; - public function new() { + public function new(?theme:ITheme) { + this.theme = theme; resources = new Resources(); loaderManager = new LoaderManager(); popupManager = new PopupManager(); diff --git a/src/main/haxework/resources/IResources.hx b/src/main/haxework/resources/IResources.hx index 4ab5d42..fc15542 100755 --- a/src/main/haxework/resources/IResources.hx +++ b/src/main/haxework/resources/IResources.hx @@ -2,7 +2,6 @@ package haxework.resources; import flash.display.BitmapData; import flash.display.MovieClip; -import haxework.view.skin.ISkin.SkinSet; import haxework.resources.Resources.ResMap; interface IResources { @@ -13,5 +12,4 @@ interface IResources { public var float(default, null):ResMap; public var int(default, null):ResMap; public var any(default, null):ResMap; - public var skin(default, null):ResMap; } diff --git a/src/main/haxework/resources/Resources.hx b/src/main/haxework/resources/Resources.hx index a352899..52a558b 100755 --- a/src/main/haxework/resources/Resources.hx +++ b/src/main/haxework/resources/Resources.hx @@ -3,7 +3,6 @@ package haxework.resources; import flash.display.BitmapData; import flash.display.MovieClip; import haxe.ds.StringMap; -import haxework.view.skin.ISkin; private typedef Listener = {object:Dynamic, field:String}; @@ -54,7 +53,6 @@ class Resources implements IResources { public var float(default, null):ResMap; public var int(default, null):ResMap; public var any(default, null):ResMap; - public var skin(default, null):ResMap; public function new() { image = new ResMap(); @@ -64,6 +62,5 @@ class Resources implements IResources { float = new ResMap(); int = new ResMap(); any = new ResMap(); - skin = new ResMap(); } } diff --git a/src/main/haxework/view/SelectView.hx b/src/main/haxework/view/SelectView.hx index cfe6ea9..d2a59b3 100644 --- a/src/main/haxework/view/SelectView.hx +++ b/src/main/haxework/view/SelectView.hx @@ -1,5 +1,6 @@ package haxework.view; +import haxework.view.core.HAlign; import flash.events.MouseEvent; import flash.geom.Point; import haxework.signal.Signal; @@ -75,6 +76,8 @@ class SelectView extends GroupView { private function factory(index:Int, value:D):LabelView { var result = new LabelView(); + result.layout.hAlign = LEFT; + result.geometry.size.percent.width = 100; result.skinId = labelSkinId; result.text = labelBuilder(value); return result; diff --git a/src/main/haxework/view/View.hx b/src/main/haxework/view/View.hx index 50e34a2..bfb6570 100755 --- a/src/main/haxework/view/View.hx +++ b/src/main/haxework/view/View.hx @@ -3,16 +3,17 @@ package haxework.view; import flash.display.DisplayObject; import flash.display.InteractiveObject; import flash.geom.Rectangle; -import haxework.resources.IResources; import haxework.view.core.Geometry; import haxework.view.skin.ISkin; +import haxework.view.theme.ITheme; class View implements IView { - @:provide private var r:IResources; private static var counter:Int = 0; public static var updater(default, null):ViewUpdater = new ViewUpdater(); + @:provide var theme:ITheme; + public var id(default, default):String; public var x(default, set):Float; @@ -134,7 +135,7 @@ class View implements IView { } private function set_skinId(value:String):String { - r.skin.bind(value, this, "skin"); + skin = theme != null ? theme.resolve(value) : []; return value; } diff --git a/src/main/haxework/view/theme/ITheme.hx b/src/main/haxework/view/theme/ITheme.hx new file mode 100644 index 0000000..0a9f703 --- /dev/null +++ b/src/main/haxework/view/theme/ITheme.hx @@ -0,0 +1,29 @@ +package haxework.view.theme; + +import haxework.color.Color; +import haxework.view.skin.ISkin; + +typedef ThemeFont = { + @:optional var name:String; + @:optional var embed:Bool; +} + +typedef ThemeColors = { + @:optional var light:Color; + @:optional var dark:Color; + @:optional var text:Color; + @:optional var border:Color; + @:optional var active:Color; +} + +interface ITheme { + public var font(default, null):ThemeFont; + public var colors(default, null):ThemeColors; + + public function resolve(id:String):SkinSet; + public function resolve2(ids:Array):SkinSet; + + // ToDo: + public function text(color:Color):ISkin; + public function textBox(color:Color):SkinSet; +} diff --git a/src/main/haxework/view/theme/Theme.hx b/src/main/haxework/view/theme/Theme.hx new file mode 100644 index 0000000..d195f06 --- /dev/null +++ b/src/main/haxework/view/theme/Theme.hx @@ -0,0 +1,95 @@ +package haxework.view.theme; + +import flash.text.FontType; +import flash.text.Font; +import haxework.color.Color; +import haxework.view.skin.ISkin; +import haxework.view.skin.Skin; +import haxework.view.theme.ITheme; + +using haxework.color.ColorUtil; + +class Theme implements ITheme { + // ToDo: configurable + public var baseFontSize = 18; + public var bigFontSize = 22; + public var veryBigFontSize = 24; + + public var font(default, null):ThemeFont; + public var colors(default, null):ThemeColors; + + private var data:Map; + + public function new(?font:ThemeFont, ?colors:ThemeColors) { + data = new Map(); + this.font = resolveFont(font); + this.colors = resolveColors(colors); + L.d("Theme", 'font: ${this.font}'); + L.d("Theme", 'colors: ${this.colors}'); + } + + private static function resolveFont(font:ThemeFont):ThemeFont { + if (font == null) { + font = {}; + } + var fonts = Font.enumerateFonts(!font.embed); + for (item in fonts) { + trace(item.fontName); + } + if (font.name == null) { + var flashFont = Font.enumerateFonts(!font.embed)[0]; + font = { + name: flashFont.fontName, + embed: switch flashFont.fontType { + case DEVICE: false; + case _: true; + } + } + } + return font; + } + + private static function resolveColors(colors:ThemeColors):ThemeColors { + if (colors == null) { + colors = {}; + } + var light:Color = colors.light != null ? colors.light : 0x33aa33; + var dark:Color = colors.dark != null ? colors.dark : light.diff(64); + var text:Color = colors.text != null ? colors.text : 0xffffff; + var border:Color = colors.border != null ? colors.border : light.multiply(1.5); + var active:Color = colors.active != null ? colors.active : 0x00ff00; + return { + light: light, + dark: dark, + text: text, + border: border, + active: active, + } + } + + public function resolve(id:String):SkinSet { + return data.exists(id) ? data.get(id) : []; + } + + public function resolve2(ids:Array):SkinSet { + var result = []; + for (id in ids) { + if (data.exists(id)) { + result = result.concat(data.get(id)); + } + } + return result; + } + + public function text(color:Color):ISkin { + return Skin.text(color, baseFontSize, font.name, font.embed); + } + + public function textBox(color:Color):SkinSet { + return [ + Skin.color(0x000000, 0.1), + Skin.border(colors.light, 1, 2), + text(color), + ]; + } +}