diff --git a/sdk/lib/rendering/box.dart b/sdk/lib/rendering/box.dart index 7f9c914ddbe0bf3257b443777a52a698d6ad4478..10fad5cc313ec45000aaf9b8b930f210b99c15da 100644 --- a/sdk/lib/rendering/box.dart +++ b/sdk/lib/rendering/box.dart @@ -1249,8 +1249,10 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin _image; @@ -1274,6 +1276,26 @@ class RenderImage extends RenderBox { markNeedsLayout(); } + sky.ColorFilter _colorFilter; + sky.ColorFilter get colorFilter => _colorFilter; + void set colorFilter (sky.ColorFilter value) { + if (value == _colorFilter) + return; + _colorFilter = value; + _cachedPaint = null; + markNeedsPaint(); + } + + Paint _cachedPaint; + Paint get _paint { + if (_cachedPaint == null) { + _cachedPaint = new Paint(); + if (colorFilter != null) + _cachedPaint.setColorFilter(colorFilter); + } + return _cachedPaint; + } + Size _sizeForConstraints(BoxConstraints innerConstraints) { // If there's no image, we can't size ourselves automatically if (_image == null) { @@ -1350,7 +1372,7 @@ class RenderImage extends RenderBox { canvas.scale(widthScale, heightScale); offset = Offset.zero; } - canvas.drawImage(_image, offset.toPoint(), new Paint()); + canvas.drawImage(_image, offset.toPoint(), _paint); if (needsScale) canvas.restore(); } diff --git a/sdk/lib/widgets/basic.dart b/sdk/lib/widgets/basic.dart index 8832969f2d0c2a622d9b60e673b0f438dc82f01f..76712c11174dbba0c22af2a609942bba7d26e3c1 100644 --- a/sdk/lib/widgets/basic.dart +++ b/sdk/lib/widgets/basic.dart @@ -485,28 +485,32 @@ class Text extends Component { } class Image extends LeafRenderObjectWrapper { - Image({ sky.Image image, this.size }) + Image({ sky.Image image, this.size, this.colorFilter }) : image = image, super(key: image.hashCode.toString()); // TODO(ianh): Find a way to uniquely identify the sky.Image rather than using hashCode, which could collide final sky.Image image; final Size size; + final sky.ColorFilter colorFilter; - RenderImage createNode() => new RenderImage(image, size); + RenderImage createNode() => new RenderImage(image, size, colorFilter: colorFilter); RenderImage get root => super.root; void syncRenderObject(Widget old) { super.syncRenderObject(old); root.image = image; root.requestedSize = size; + root.colorFilter = colorFilter; } } class FutureImage extends StatefulComponent { - FutureImage({ String key, this.image, this.size }) : super(key: key); + FutureImage({ String key, this.image, this.size, this.colorFilter }) + : super(key: key); Future image; Size size; + sky.ColorFilter colorFilter; sky.Image _resolvedImage; @@ -534,34 +538,44 @@ class FutureImage extends StatefulComponent { } Widget build() { - return new Image(image: _resolvedImage, size: size); + return new Image(image: _resolvedImage, size: size, colorFilter: colorFilter); } } class NetworkImage extends Component { - NetworkImage({ String src, this.size }) + NetworkImage({ String src, this.size, this.colorFilter }) : src = src, super(key: src); final String src; final Size size; + final sky.ColorFilter colorFilter; Widget build() { - return new FutureImage(image: image_cache.load(src), size: size); + return new FutureImage( + image: image_cache.load(src), + size: size, + colorFilter: colorFilter + ); } } class AssetImage extends Component { - AssetImage({ String name, this.bundle, this.size }) + AssetImage({ String name, this.bundle, this.size, this.colorFilter }) : name = name, super(key: name); final String name; final AssetBundle bundle; final Size size; + final sky.ColorFilter colorFilter; Widget build() { - return new FutureImage(image: bundle.loadImage(name), size: size); + return new FutureImage( + image: bundle.loadImage(name), + size: size, + colorFilter: colorFilter + ); } } diff --git a/sdk/lib/widgets/drawer_item.dart b/sdk/lib/widgets/drawer_item.dart index 8b517116775bba6ee286356c0d5aece167bcb2e9..d807bd89c72da7d57feb6138a5c16b7babd6231d 100644 --- a/sdk/lib/widgets/drawer_item.dart +++ b/sdk/lib/widgets/drawer_item.dart @@ -46,26 +46,24 @@ class DrawerItem extends ButtonBase { return colors.transparent; } + sky.ColorFilter _getColorFilter(ThemeData themeData) { + if (selected) + return new sky.ColorFilter.mode(themeData.primaryColor, sky.TransferMode.srcATop); + return new sky.ColorFilter.mode(const Color(0x73000000), sky.TransferMode.dstIn); + } + Widget buildContent() { ThemeData themeData = Theme.of(this); List flexChildren = new List(); if (icon != null) { - Widget child = new Icon(type: icon, size: 24); - if (selected) { - child = new ColorFilter( - color: themeData.primaryColor, - transferMode: sky.TransferMode.srcATop, - child: child - ); - } flexChildren.add( - new Opacity( - opacity: selected ? 1.0 : 0.45, - child: new Padding( - padding: const EdgeDims.symmetric(horizontal: 16.0), - child: child - ) + new Padding( + padding: const EdgeDims.symmetric(horizontal: 16.0), + child: new Icon( + type: icon, + size: 24, + colorFilter: _getColorFilter(themeData)) ) ); } diff --git a/sdk/lib/widgets/icon.dart b/sdk/lib/widgets/icon.dart index 05bbcb8fc82cd9c0196877e5dd30805387029054..7229d9e17f0b238b4e128f4e742998e6278ec271 100644 --- a/sdk/lib/widgets/icon.dart +++ b/sdk/lib/widgets/icon.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:sky' as sky; + import 'package:sky/mojo/asset_bundle.dart'; import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/theme.dart'; @@ -46,11 +48,18 @@ AssetBundle _initIconBundle() { final AssetBundle _iconBundle = _initIconBundle(); class Icon extends Component { - Icon({ String key, this.size, this.type: '', this.color }) : super(key: key); + Icon({ + String key, + this.size, + this.type: '', + this.color, + this.colorFilter + }) : super(key: key); final int size; final String type; final IconThemeColor color; + final sky.ColorFilter colorFilter; String get colorSuffix { IconThemeColor iconThemeColor = color; @@ -84,7 +93,8 @@ class Icon extends Component { return new AssetImage( bundle: _iconBundle, name: '${category}/${density}/ic_${subtype}_${colorSuffix}_${size}dp.png', - size: new Size(size.toDouble(), size.toDouble()) + size: new Size(size.toDouble(), size.toDouble()), + colorFilter: colorFilter ); } } diff --git a/services/engine/input_event.mojom b/services/engine/input_event.mojom index d57a5c08710326baee791af53619aabdad41b5f7..eb7c4d1ae8e6ec9c144dc558f1d5bfc12ed3c077 100644 --- a/services/engine/input_event.mojom +++ b/services/engine/input_event.mojom @@ -56,6 +56,8 @@ struct GestureData { float velocityY; }; +// TODO(abarth): Should we have a malloc-free way of creating an input event +// message? What we have now could stress out the Android Java GC. struct InputEvent { EventType type; int64 time_stamp; diff --git a/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java b/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java index be7dbf41d6bebdaf0c4785824ccc3c0bef9a12b5..a9e4dbb1fdbb975d803b2c116c1ca121185588b6 100644 --- a/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java +++ b/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java @@ -5,6 +5,7 @@ package org.domokit.sky.shell; import android.content.Context; +import android.os.Build; import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceHolder; @@ -170,15 +171,23 @@ public class PlatformViewAndroid extends SurfaceView inputEvent.timeStamp = event.getEventTime(); inputEvent.pointerData = pointerData; - - mSkyEngine.onInputEvent(inputEvent); } @Override public boolean onTouchEvent(MotionEvent event) { + // TODO(abarth): This version check might not be effective in some + // versions of Android that statically compile code and will be upset + // at the lack of |requestUnbufferedDispatch|. Instead, we should factor + // version-dependent code into separate classes for each supported + // version and dispatch dynamically. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + requestUnbufferedDispatch(event); + } mGestureProvider.onTouchEvent(event); + // TODO(abarth): Rather than unpacking these events here, we should + // probably send them in one packet to the engine. int maskedAction = event.getActionMasked(); // ACTION_UP, ACTION_POINTER_UP, ACTION_DOWN, and ACTION_POINTER_DOWN // only apply to a single pointer, other events apply to all pointers.