Merge branch 'feature/dev' into 'master'

Feature/dev



See merge request !34
This commit is contained in:
pengfeizhou 2019-11-29 10:51:20 +08:00
commit 50a1eb4db8
26 changed files with 498 additions and 44 deletions

View File

@ -22,6 +22,7 @@ import com.github.pengfeizhou.jscore.JSONBuilder;
import org.json.JSONObject;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@ -30,6 +31,7 @@ import pub.doric.navbar.IDoricNavBar;
import pub.doric.navigator.IDoricNavigator;
import pub.doric.plugin.DoricJavaPlugin;
import pub.doric.shader.RootNode;
import pub.doric.shader.ViewNode;
import pub.doric.utils.DoricConstant;
import pub.doric.utils.DoricMetaInfo;
@ -47,6 +49,26 @@ public class DoricContext {
private String script;
private JSONObject initParams;
private IDoricDriver doricDriver;
private final Map<String, ViewNode> mHeadNodes = new HashMap<>();
public Collection<ViewNode> allHeadNodes() {
return mHeadNodes.values();
}
public void addHeadNode(ViewNode viewNode) {
mHeadNodes.put(viewNode.getId(), viewNode);
}
public void removeHeadNode(ViewNode viewNode) {
mHeadNodes.remove(viewNode.getId());
}
public ViewNode targetViewNode(String id) {
if (id.equals(mRootNode.getId())) {
return mRootNode;
}
return mHeadNodes.get(id);
}
protected DoricContext(Context context, String contextId, String source) {
this.mContext = context;

View File

@ -23,6 +23,7 @@ import pub.doric.loader.IDoricJSLoader;
import pub.doric.plugin.NavBarPlugin;
import pub.doric.plugin.NavigatorPlugin;
import pub.doric.plugin.NetworkPlugin;
import pub.doric.plugin.PopoverPlugin;
import pub.doric.plugin.ShaderPlugin;
import pub.doric.plugin.StoragePlugin;
import pub.doric.refresh.RefreshableNode;
@ -87,6 +88,7 @@ public class DoricRegistry {
this.registerNativePlugin(StoragePlugin.class);
this.registerNativePlugin(NavigatorPlugin.class);
this.registerNativePlugin(NavBarPlugin.class);
this.registerNativePlugin(PopoverPlugin.class);
this.registerViewNode(RootNode.class);
this.registerViewNode(TextNode.class);

View File

@ -58,6 +58,10 @@ public class DoricBridgeExtension {
return new JavaValue(false);
}
DoricMethod doricMethod = method.getAnnotation(DoricMethod.class);
if (doricMethod == null) {
DoricLog.e("Cannot find DoricMethod annotation in class:%s,method:%s", module, methodName);
return new JavaValue(false);
}
Callable<JavaValue> callable = new Callable<JavaValue>() {
@Override
public JavaValue call() throws Exception {

View File

@ -50,9 +50,8 @@ public class ModalPlugin extends DoricJavaPlugin {
}
@DoricMethod(thread = ThreadMode.UI)
public void toast(JSDecoder decoder) {
public void toast(JSObject jsObject) {
try {
JSObject jsObject = decoder.decode().asObject();
String msg = jsObject.getProperty("msg").asString().value();
JSValue gravityVal = jsObject.getProperty("gravity");
int gravity = Gravity.BOTTOM;
@ -77,9 +76,8 @@ public class ModalPlugin extends DoricJavaPlugin {
}
@DoricMethod(thread = ThreadMode.UI)
public void alert(JSDecoder decoder, final DoricPromise promise) {
public void alert(JSObject jsObject, final DoricPromise promise) {
try {
JSObject jsObject = decoder.decode().asObject();
JSValue titleVal = jsObject.getProperty("title");
JSValue msgVal = jsObject.getProperty("msg");
JSValue okBtn = jsObject.getProperty("okLabel");
@ -109,9 +107,8 @@ public class ModalPlugin extends DoricJavaPlugin {
@DoricMethod(thread = ThreadMode.UI)
public void confirm(JSDecoder decoder, final DoricPromise promise) {
public void confirm(JSObject jsObject, final DoricPromise promise) {
try {
JSObject jsObject = decoder.decode().asObject();
JSValue titleVal = jsObject.getProperty("title");
JSValue msgVal = jsObject.getProperty("msg");
JSValue okBtn = jsObject.getProperty("okLabel");
@ -152,9 +149,8 @@ public class ModalPlugin extends DoricJavaPlugin {
@DoricMethod(thread = ThreadMode.UI)
public void prompt(JSDecoder decoder, final DoricPromise promise) {
public void prompt(JSObject jsObject, final DoricPromise promise) {
try {
JSObject jsObject = decoder.decode().asObject();
JSValue titleVal = jsObject.getProperty("title");
JSValue msgVal = jsObject.getProperty("msg");
JSValue okBtn = jsObject.getProperty("okLabel");

View File

@ -58,9 +58,8 @@ public class NetworkPlugin extends DoricJavaPlugin {
}
@DoricMethod
public void request(JSDecoder decoder, final DoricPromise promise) {
public void request(JSObject requestVal, final DoricPromise promise) {
try {
JSObject requestVal = decoder.decode().asObject();
String url = requestVal.getProperty("url").asString().value();
String method = requestVal.getProperty("method").asString().value();
JSValue headerVal = requestVal.getProperty("headers");

View File

@ -0,0 +1,139 @@
package pub.doric.plugin;
import android.app.Activity;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
import com.github.pengfeizhou.jscore.JavaValue;
import java.util.concurrent.Callable;
import pub.doric.DoricContext;
import pub.doric.async.AsyncCall;
import pub.doric.async.AsyncResult;
import pub.doric.extension.bridge.DoricMethod;
import pub.doric.extension.bridge.DoricPlugin;
import pub.doric.extension.bridge.DoricPromise;
import pub.doric.shader.ViewNode;
import pub.doric.utils.ThreadMode;
/**
* @Description: pub.doric.plugin
* @Author: pengfei.zhou
* @CreateDate: 2019-11-29
*/
@DoricPlugin(name = "popover")
public class PopoverPlugin extends DoricJavaPlugin {
private FrameLayout mFullScreenView;
public PopoverPlugin(DoricContext doricContext) {
super(doricContext);
}
@DoricMethod
public void show(JSDecoder decoder, final DoricPromise promise) {
try {
final JSObject jsObject = decoder.decode().asObject();
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (mFullScreenView == null) {
mFullScreenView = new FrameLayout(getDoricContext().getContext());
ViewGroup decorView = (ViewGroup) getDoricContext().getRootNode().getNodeView().getRootView();
decorView.addView(mFullScreenView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
}
mFullScreenView.setVisibility(View.VISIBLE);
mFullScreenView.bringToFront();
String viewId = jsObject.getProperty("id").asString().value();
String type = jsObject.getProperty("type").asString().value();
ViewNode node = ViewNode.create(getDoricContext(), type);
node.setId(viewId);
node.init(new FrameLayout.LayoutParams(0, 0));
node.blend(jsObject.getProperty("props").asObject());
mFullScreenView.addView(node.getNodeView());
getDoricContext().addHeadNode(node);
return null;
}
}, ThreadMode.UI).setCallback(new AsyncResult.Callback<Object>() {
@Override
public void onResult(Object result) {
promise.resolve();
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
promise.reject(new JavaValue(t.getLocalizedMessage()));
}
@Override
public void onFinish() {
}
});
} catch (Exception e) {
e.printStackTrace();
promise.reject(new JavaValue(e.getLocalizedMessage()));
}
}
@DoricMethod
public void dismiss(final JSValue value, final DoricPromise promise) {
try {
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (value.isObject()) {
String viewId = value.asObject().getProperty("id").asString().value();
ViewNode node = getDoricContext().targetViewNode(viewId);
dismissViewNode(node);
} else {
dismissPopover();
}
return null;
}
}, ThreadMode.UI).setCallback(new AsyncResult.Callback<Object>() {
@Override
public void onResult(Object result) {
promise.resolve();
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
promise.reject(new JavaValue(t.getLocalizedMessage()));
}
@Override
public void onFinish() {
}
});
} catch (Exception e) {
e.printStackTrace();
promise.reject(new JavaValue(e.getLocalizedMessage()));
}
}
private void dismissViewNode(ViewNode node) {
getDoricContext().removeHeadNode(node);
mFullScreenView.removeView(node.getNodeView());
if (getDoricContext().allHeadNodes().isEmpty()) {
mFullScreenView.setVisibility(View.GONE);
}
}
private void dismissPopover() {
for (ViewNode node : getDoricContext().allHeadNodes()) {
dismissViewNode(node);
}
}
}

View File

@ -15,6 +15,8 @@
*/
package pub.doric.plugin;
import android.text.TextUtils;
import pub.doric.DoricContext;
import pub.doric.async.AsyncResult;
import pub.doric.extension.bridge.DoricMethod;
@ -55,9 +57,17 @@ public class ShaderPlugin extends DoricJavaPlugin {
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override
public Object call() throws Exception {
String viewId = jsObject.getProperty("id").asString().value();
RootNode rootNode = getDoricContext().getRootNode();
rootNode.setId(jsObject.getProperty("id").asString().value());
rootNode.render(jsObject.getProperty("props").asObject());
if (TextUtils.isEmpty(rootNode.getId())) {
rootNode.setId(viewId);
rootNode.blend(jsObject.getProperty("props").asObject());
} else {
ViewNode viewNode = getDoricContext().targetViewNode(viewId);
if (viewNode != null) {
viewNode.blend(jsObject.getProperty("props").asObject());
}
}
return null;
}
}, ThreadMode.UI).setCallback(new AsyncResult.Callback<Object>() {
@ -93,7 +103,7 @@ public class ShaderPlugin extends DoricJavaPlugin {
ViewNode viewNode = null;
for (JSValue value : viewIds) {
if (viewNode == null) {
viewNode = getDoricContext().getRootNode();
viewNode = getDoricContext().targetViewNode(value.asString().value());
} else {
if (value.isString() && viewNode instanceof SuperNode) {
String viewId = value.asString().value();

View File

@ -41,9 +41,8 @@ public class StoragePlugin extends DoricJavaPlugin {
}
@DoricMethod
public void setItem(JSDecoder decoder, final DoricPromise promise) {
public void setItem(JSObject jsObject, final DoricPromise promise) {
try {
JSObject jsObject = decoder.decode().asObject();
JSValue zone = jsObject.getProperty("zone");
String key = jsObject.getProperty("key").asString().value();
String value = jsObject.getProperty("value").asString().value();
@ -59,9 +58,8 @@ public class StoragePlugin extends DoricJavaPlugin {
}
@DoricMethod
public void getItem(JSDecoder decoder, final DoricPromise promise) {
public void getItem(JSObject jsObject, final DoricPromise promise) {
try {
JSObject jsObject = decoder.decode().asObject();
JSValue zone = jsObject.getProperty("zone");
String key = jsObject.getProperty("key").asString().value();
String prefName = zone.isString() ? PREF_NAME + "_" + zone.asString() : PREF_NAME;
@ -76,9 +74,8 @@ public class StoragePlugin extends DoricJavaPlugin {
}
@DoricMethod
public void remove(JSDecoder decoder, final DoricPromise promise) {
public void remove(JSObject jsObject, final DoricPromise promise) {
try {
JSObject jsObject = decoder.decode().asObject();
JSValue zone = jsObject.getProperty("zone");
String key = jsObject.getProperty("key").asString().value();
String prefName = zone.isString() ? PREF_NAME + "_" + zone.asString() : PREF_NAME;
@ -93,9 +90,8 @@ public class StoragePlugin extends DoricJavaPlugin {
}
@DoricMethod
public void clear(JSDecoder decoder, final DoricPromise promise) {
public void clear(JSObject jsObject, final DoricPromise promise) {
try {
JSObject jsObject = decoder.decode().asObject();
JSValue zone = jsObject.getProperty("zone");
if (zone.isString()) {
String prefName = PREF_NAME + "_" + zone.asString();

View File

@ -53,8 +53,4 @@ public class RootNode extends StackNode {
public ViewGroup.LayoutParams getLayoutParams() {
return mView.getLayoutParams();
}
public void render(JSObject props) {
blend(props);
}
}

View File

@ -66,6 +66,12 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
this.mView.setLayoutParams(mLayoutParams);
}
public void init(ViewGroup.LayoutParams layoutParams) {
this.mLayoutParams = layoutParams;
this.mView = build();
this.mView.setLayoutParams(layoutParams);
}
public void setId(String id) {
this.mId = id;
}
@ -265,6 +271,61 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
protected void setLayoutConfig(JSObject layoutConfig) {
if (mSuperNode != null) {
mSuperNode.blendSubLayoutConfig(this, layoutConfig);
} else {
blendLayoutConfig(layoutConfig);
}
}
private void blendLayoutConfig(JSObject jsObject) {
JSValue margin = jsObject.getProperty("margin");
JSValue widthSpec = jsObject.getProperty("widthSpec");
JSValue heightSpec = jsObject.getProperty("heightSpec");
ViewGroup.LayoutParams layoutParams = getLayoutParams();
if (widthSpec.isNumber()) {
switch (widthSpec.asNumber().toInt()) {
case 1:
layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
break;
case 2:
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
break;
default:
break;
}
}
if (heightSpec.isNumber()) {
switch (heightSpec.asNumber().toInt()) {
case 1:
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
break;
case 2:
layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
break;
default:
break;
}
}
if (margin.isObject() && layoutParams instanceof ViewGroup.MarginLayoutParams) {
JSValue topVal = margin.asObject().getProperty("top");
if (topVal.isNumber()) {
((ViewGroup.MarginLayoutParams) layoutParams).topMargin = DoricUtils.dp2px(topVal.asNumber().toFloat());
}
JSValue leftVal = margin.asObject().getProperty("left");
if (leftVal.isNumber()) {
((ViewGroup.MarginLayoutParams) layoutParams).leftMargin = DoricUtils.dp2px(leftVal.asNumber().toFloat());
}
JSValue rightVal = margin.asObject().getProperty("right");
if (rightVal.isNumber()) {
((ViewGroup.MarginLayoutParams) layoutParams).rightMargin = DoricUtils.dp2px(rightVal.asNumber().toFloat());
}
JSValue bottomVal = margin.asObject().getProperty("bottom");
if (bottomVal.isNumber()) {
((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin = DoricUtils.dp2px(bottomVal.asNumber().toFloat());
}
}
JSValue jsValue = jsObject.getProperty("alignment");
if (jsValue.isNumber() && layoutParams instanceof FrameLayout.LayoutParams) {
((FrameLayout.LayoutParams) layoutParams).gravity = jsValue.asNumber().toInt();
}
}

View File

@ -14,4 +14,5 @@ export default [
'src/NavbarDemo',
'src/RefreshableDemo',
'src/FlowLayoutDemo',
'src/PopoverDemo'
]

44
demo/src/PopoverDemo.ts Normal file
View File

@ -0,0 +1,44 @@
import { Group, Panel, popover, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, Text, scroller, layoutConfig, image, IView, IVLayout, ScaleType, modal, IText, network } from "doric";
import { title, label, colors } from "./utils";
@Entry
class PopoverDemo extends Panel {
build(rootView: Group): void {
scroller(vlayout([
title("Popover Demo"),
label('Popover').apply({
width: 200,
height: 50,
bgColor: colors[0],
textSize: 30,
textColor: Color.WHITE,
layoutConfig: layoutConfig().exactly(),
onClick: () => {
popover(context).show(text({
width: 200,
height: 50,
bgColor: colors[0],
textColor: Color.WHITE,
layoutConfig: layoutConfig().exactly().a(Gravity.Center),
text: "This is PopOver Window",
}).also(v => {
let idx = 0
v.onClick = () => {
v.bgColor = colors[(++idx) % colors.length]
}
modal(context).toast('Dismissed after 3 seconds')
setTimeout(() => {
popover(context).dismiss()
}, 3000)
}))
}
} as IText),
]).apply({
layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT),
gravity: gravity().center(),
space: 10,
} as IVLayout)).apply({
layoutConfig: layoutConfig().atmost(),
}).in(rootView)
}
}

View File

@ -27,6 +27,7 @@
NS_ASSUME_NONNULL_BEGIN
@class DoricViewNode;
@class DoricRootNode;
@interface DoricContext : NSObject
@ -35,10 +36,11 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, strong) NSString *contextId;
@property(nonatomic, strong) DoricDriver *driver;
@property(nonatomic, strong) NSMutableDictionary *pluginInstanceMap;
@property(nonatomic, strong) DoricRootNode *rootNode;
@property(nonatomic, strong) NSString *source;
@property(nonatomic, strong) NSString *script;;
@property(nonatomic, strong) NSMutableDictionary *initialParams;
@property(nonatomic, strong) DoricRootNode *rootNode;
@property(nonatomic, strong) NSMutableDictionary <NSString *, DoricViewNode *> *headNodes;
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source;
@ -56,6 +58,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onHidden;
- (DoricViewNode *)targetViewNode:(NSString *)viewId;
@end
NS_ASSUME_NONNULL_END

View File

@ -31,9 +31,11 @@ @implementation DoricContext
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source {
if (self = [super init]) {
_driver = [DoricDriver instance];
_pluginInstanceMap = [[NSMutableDictionary alloc] init];
_pluginInstanceMap = [NSMutableDictionary new];
[[DoricContextManager instance] createContext:self script:script source:source];
_rootNode = [[DoricRootNode alloc] initWithContext:self];
_headNodes = [NSMutableDictionary new];
DoricRootNode *rootNode = [[DoricRootNode alloc] initWithContext:self];
_rootNode = rootNode;
_script = script;
_source = source;
_initialParams = [@{@"width": @(0), @"height": @(0)} mutableCopy];
@ -42,6 +44,14 @@ - (instancetype)initWithScript:(NSString *)script source:(NSString *)source {
return self;
}
- (DoricViewNode *)targetViewNode:(NSString *)viewId {
if ([self.rootNode.viewId isEqualToString:viewId]) {
return self.rootNode;
} else {
return self.headNodes[viewId];
}
}
- (void)dealloc {
[self callEntity:DORIC_ENTITY_DESTROY, nil];
[[DoricContextManager instance] destroyContext:self];

View File

@ -40,6 +40,7 @@
#import "DoricRefreshableNode.h"
#import "DoricFlowLayoutItemNode.h"
#import "DoricFlowLayoutNode.h"
#import "DoricPopoverPlugin.h"
@interface DoricRegistry ()
@ -68,6 +69,7 @@ - (void)innerRegister {
[self registerNativePlugin:DoricStoragePlugin.class withName:@"storage"];
[self registerNativePlugin:DoricNavigatorPlugin.class withName:@"navigator"];
[self registerNativePlugin:DoricNavBarPlugin.class withName:@"navbar"];
[self registerNativePlugin:DoricPopoverPlugin.class withName:@"popover"];
[self registerViewNode:DoricStackNode.class withName:@"Stack"];
[self registerViewNode:DoricVLayoutNode.class withName:@"VLayout"];

View File

@ -0,0 +1,9 @@
//
// Created by pengfei.zhou on 2019/11/28.
//
#import <Foundation/Foundation.h>
#import "DoricNativePlugin.h"
@interface DoricPopoverPlugin : DoricNativePlugin
@end

View File

@ -0,0 +1,70 @@
//
// Created by pengfei.zhou on 2019/11/28.
//
#import "DoricPopoverPlugin.h"
#import "DoricRootNode.h"
#import "Doric.h"
@interface DoricPopoverPlugin ()
@property(nonatomic, strong) UIView *fullScreenView;
@end
@implementation DoricPopoverPlugin
- (void)show:(NSDictionary *)params withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
UIView *superView = [UIApplication sharedApplication].windows.lastObject;
if (!self.fullScreenView) {
self.fullScreenView = [[DoricStackView new] also:^(UIView *it) {
it.width = superView.width;
it.height = superView.height;
it.top = it.left = 0;
[superView addSubview:it];
}];
}
[superView bringSubviewToFront:self.fullScreenView];
self.fullScreenView.hidden = NO;
NSString *viewId = params[@"id"];
NSString *type = params[@"type"];
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
if (!viewNode) {
viewNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) {
it.viewId = viewId;
[it initWithSuperNode:nil];
it.view.layoutConfig = [DoricLayoutConfig new];
[self.fullScreenView addSubview:it.view];
self.doricContext.headNodes[viewId] = it;
}];
}
[viewNode blend:params[@"props"]];
[promise resolve:nil];
});
}
- (void)dismiss:(NSDictionary *)params withPromise:(DoricPromise *)promise {
NSString *viewId = params[@"id"];
dispatch_async(dispatch_get_main_queue(), ^{
if (viewId) {
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
[self dismissViewNode:viewNode];
} else {
[self dismissPopover];
}
[promise resolve:nil];
});
}
- (void)dismissViewNode:(DoricViewNode *)node {
[self.doricContext.headNodes removeObjectForKey:node.viewId];
[node.view removeFromSuperview];
if (self.doricContext.headNodes.count == 0) {
self.fullScreenView.hidden = YES;
}
}
- (void)dismissPopover {
for (DoricViewNode *node in self.doricContext.headNodes.allValues) {
[self dismissViewNode:node];
}
}
@end

View File

@ -36,10 +36,16 @@ - (void)render:(NSDictionary *)argument {
__weak typeof(self) _self = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(_self) self = _self;
[self.doricContext.rootNode also:^(DoricRootNode *it) {
it.viewId = argument[@"id"];
[it render:argument[@"props"]];
}];
NSString *viewId = argument[@"id"];
if (self.doricContext.rootNode.viewId == nil) {
self.doricContext.rootNode.viewId = viewId;
[self.doricContext.rootNode blend:argument[@"props"]];
} else {
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
[viewNode blend:argument[@"props"]];
}
});
}
@ -50,7 +56,7 @@ - (id)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
DoricViewNode *viewNode = nil;
for (NSString *viewId in viewIds) {
if (!viewNode) {
viewNode = self.doricContext.rootNode;
viewNode = [self.doricContext targetViewNode:viewId];
} else {
if ([viewNode isKindOfClass:[DoricSuperNode class]]) {
viewNode = [((DoricSuperNode *) viewNode) subNodeWithViewId:viewId];

View File

@ -28,7 +28,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)setupRootView:(DoricStackView *)view;
- (void)render:(NSDictionary *)props;
@end
NS_ASSUME_NONNULL_END

View File

@ -27,9 +27,6 @@ - (void)setupRootView:(DoricStackView *)view {
self.view = view;
}
- (void)render:(NSDictionary *)props {
[self blend:props];
}
- (void)requestLayout {
[self.view setNeedsLayout];
}

View File

@ -24,7 +24,6 @@
#import "DoricLayouts.h"
#import "UIView+Doric.h"
NS_ASSUME_NONNULL_BEGIN
@class DoricSuperNode;
@interface DoricViewNode <V:UIView *> : DoricContextHolder
@ -55,5 +54,3 @@ NS_ASSUME_NONNULL_BEGIN
- (void)requestLayout;
@end
NS_ASSUME_NONNULL_END

View File

@ -126,6 +126,8 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
} else if ([name isEqualToString:@"layoutConfig"]) {
if (self.superNode && [prop isKindOfClass:[NSDictionary class]]) {
[self.superNode blendSubNode:self layoutConfig:prop];
} else {
[self blendLayoutConfig:prop];
}
} else if ([name isEqualToString:@"onClick"]) {
self.callbackIds[@"onClick"] = prop;
@ -246,4 +248,36 @@ - (NSNumber *)getRotation {
return @(degree);
}
- (void)blendLayoutConfig:(NSDictionary *)params {
[params[@"widthSpec"] also:^(NSNumber *it) {
if (it) {
self.layoutConfig.widthSpec = (DoricLayoutSpec) [it integerValue];
}
}];
[params[@"heightSpec"] also:^(NSNumber *it) {
if (it) {
self.layoutConfig.heightSpec = (DoricLayoutSpec) [it integerValue];
}
}];
NSDictionary *margin = params[@"margin"];
if (margin) {
self.layoutConfig.margin = DoricMarginMake(
[(NSNumber *) margin[@"left"] floatValue],
[(NSNumber *) margin[@"top"] floatValue],
[(NSNumber *) margin[@"right"] floatValue],
[(NSNumber *) margin[@"bottom"] floatValue]);
}
NSNumber *alignment = params[@"alignment"];
if (alignment) {
self.layoutConfig.alignment = (DoricGravity) [alignment integerValue];
}
NSNumber *weight = params[@"weight"];
if (weight) {
self.layoutConfig.weight = (DoricGravity) [weight integerValue];
}
}
@end

View File

@ -18,3 +18,4 @@ export * from './navbar'
export * from './navigator'
export * from './network'
export * from './storage'
export * from './popover'

View File

@ -1,4 +1,3 @@
/*
* Copyright [2019] [Doric.Pub]
*

View File

@ -0,0 +1,44 @@
/*
* Copyright [2019] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BridgeContext } from "../runtime/global"
import { View } from "../ui/view"
import { Panel } from "../ui/panel"
export function popover(context: BridgeContext) {
const entity = context.entity
let panel: Panel | undefined = undefined
if (entity instanceof Panel) {
panel = entity
}
return {
show: (view: View) => {
if (panel) {
panel.addHeadView(view)
}
return context.popover.show(view.toModel())
},
dismiss: (view: View | undefined = undefined) => {
if (panel) {
if (view) {
panel.removeHeadView(view)
} else {
panel.clearHeadViews()
}
}
return context.popover.dismiss(view ? { id: view.viewId } : undefined)
},
}
}

View File

@ -58,6 +58,10 @@ export abstract class Panel {
}
}
clearHeadViews() {
this.headviews.clear()
}
getRootView() {
return this.__root__
}
@ -65,9 +69,6 @@ export abstract class Panel {
getInitData() {
return this.__data__
}
constructor() {
this.addHeadView(this.__root__)
}
@NativeCall
private __init__(frame: Frame, data: any) {
@ -120,6 +121,9 @@ export abstract class Panel {
private retrospectView(ids: string[]): View | undefined {
return ids.reduce((acc: View | undefined, cur) => {
if (acc === undefined) {
if (cur === this.__root__.viewId) {
return this.__root__
}
return this.headviews.get(cur)
} else {
if (Reflect.has(acc, "subviewById")) {
@ -138,6 +142,9 @@ export abstract class Panel {
private hookBeforeNativeCall() {
this.__root__.clean()
for (let v of this.headviews.values()) {
v.clean()
}
}
private hookAfterNativeCall() {
@ -147,6 +154,12 @@ export abstract class Panel {
const model = this.__root__.toModel()
this.nativeRender(model)
}
for (let v of this.headviews.values()) {
if (v.isDirty()) {
const model = v.toModel()
this.nativeRender(model)
}
}
}
}