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 org.json.JSONObject;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -30,6 +31,7 @@ import pub.doric.navbar.IDoricNavBar;
import pub.doric.navigator.IDoricNavigator; import pub.doric.navigator.IDoricNavigator;
import pub.doric.plugin.DoricJavaPlugin; import pub.doric.plugin.DoricJavaPlugin;
import pub.doric.shader.RootNode; import pub.doric.shader.RootNode;
import pub.doric.shader.ViewNode;
import pub.doric.utils.DoricConstant; import pub.doric.utils.DoricConstant;
import pub.doric.utils.DoricMetaInfo; import pub.doric.utils.DoricMetaInfo;
@ -47,6 +49,26 @@ public class DoricContext {
private String script; private String script;
private JSONObject initParams; private JSONObject initParams;
private IDoricDriver doricDriver; 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) { protected DoricContext(Context context, String contextId, String source) {
this.mContext = context; this.mContext = context;

View File

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

View File

@ -58,6 +58,10 @@ public class DoricBridgeExtension {
return new JavaValue(false); return new JavaValue(false);
} }
DoricMethod doricMethod = method.getAnnotation(DoricMethod.class); 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>() { Callable<JavaValue> callable = new Callable<JavaValue>() {
@Override @Override
public JavaValue call() throws Exception { public JavaValue call() throws Exception {

View File

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

View File

@ -58,9 +58,8 @@ public class NetworkPlugin extends DoricJavaPlugin {
} }
@DoricMethod @DoricMethod
public void request(JSDecoder decoder, final DoricPromise promise) { public void request(JSObject requestVal, final DoricPromise promise) {
try { try {
JSObject requestVal = decoder.decode().asObject();
String url = requestVal.getProperty("url").asString().value(); String url = requestVal.getProperty("url").asString().value();
String method = requestVal.getProperty("method").asString().value(); String method = requestVal.getProperty("method").asString().value();
JSValue headerVal = requestVal.getProperty("headers"); 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; package pub.doric.plugin;
import android.text.TextUtils;
import pub.doric.DoricContext; import pub.doric.DoricContext;
import pub.doric.async.AsyncResult; import pub.doric.async.AsyncResult;
import pub.doric.extension.bridge.DoricMethod; import pub.doric.extension.bridge.DoricMethod;
@ -55,9 +57,17 @@ public class ShaderPlugin extends DoricJavaPlugin {
getDoricContext().getDriver().asyncCall(new Callable<Object>() { getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override @Override
public Object call() throws Exception { public Object call() throws Exception {
String viewId = jsObject.getProperty("id").asString().value();
RootNode rootNode = getDoricContext().getRootNode(); RootNode rootNode = getDoricContext().getRootNode();
rootNode.setId(jsObject.getProperty("id").asString().value()); if (TextUtils.isEmpty(rootNode.getId())) {
rootNode.render(jsObject.getProperty("props").asObject()); 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; return null;
} }
}, ThreadMode.UI).setCallback(new AsyncResult.Callback<Object>() { }, ThreadMode.UI).setCallback(new AsyncResult.Callback<Object>() {
@ -93,7 +103,7 @@ public class ShaderPlugin extends DoricJavaPlugin {
ViewNode viewNode = null; ViewNode viewNode = null;
for (JSValue value : viewIds) { for (JSValue value : viewIds) {
if (viewNode == null) { if (viewNode == null) {
viewNode = getDoricContext().getRootNode(); viewNode = getDoricContext().targetViewNode(value.asString().value());
} else { } else {
if (value.isString() && viewNode instanceof SuperNode) { if (value.isString() && viewNode instanceof SuperNode) {
String viewId = value.asString().value(); String viewId = value.asString().value();

View File

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

View File

@ -53,8 +53,4 @@ public class RootNode extends StackNode {
public ViewGroup.LayoutParams getLayoutParams() { public ViewGroup.LayoutParams getLayoutParams() {
return mView.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); 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) { public void setId(String id) {
this.mId = id; this.mId = id;
} }
@ -265,6 +271,61 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
protected void setLayoutConfig(JSObject layoutConfig) { protected void setLayoutConfig(JSObject layoutConfig) {
if (mSuperNode != null) { if (mSuperNode != null) {
mSuperNode.blendSubLayoutConfig(this, layoutConfig); 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/NavbarDemo',
'src/RefreshableDemo', 'src/RefreshableDemo',
'src/FlowLayoutDemo', '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 NS_ASSUME_NONNULL_BEGIN
@class DoricViewNode;
@class DoricRootNode; @class DoricRootNode;
@interface DoricContext : NSObject @interface DoricContext : NSObject
@ -35,10 +36,11 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, strong) NSString *contextId; @property(nonatomic, strong) NSString *contextId;
@property(nonatomic, strong) DoricDriver *driver; @property(nonatomic, strong) DoricDriver *driver;
@property(nonatomic, strong) NSMutableDictionary *pluginInstanceMap; @property(nonatomic, strong) NSMutableDictionary *pluginInstanceMap;
@property(nonatomic, strong) DoricRootNode *rootNode;
@property(nonatomic, strong) NSString *source; @property(nonatomic, strong) NSString *source;
@property(nonatomic, strong) NSString *script;; @property(nonatomic, strong) NSString *script;;
@property(nonatomic, strong) NSMutableDictionary *initialParams; @property(nonatomic, strong) NSMutableDictionary *initialParams;
@property(nonatomic, strong) DoricRootNode *rootNode;
@property(nonatomic, strong) NSMutableDictionary <NSString *, DoricViewNode *> *headNodes;
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source; - (instancetype)initWithScript:(NSString *)script source:(NSString *)source;
@ -56,6 +58,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onHidden; - (void)onHidden;
- (DoricViewNode *)targetViewNode:(NSString *)viewId;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

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

View File

@ -40,6 +40,7 @@
#import "DoricRefreshableNode.h" #import "DoricRefreshableNode.h"
#import "DoricFlowLayoutItemNode.h" #import "DoricFlowLayoutItemNode.h"
#import "DoricFlowLayoutNode.h" #import "DoricFlowLayoutNode.h"
#import "DoricPopoverPlugin.h"
@interface DoricRegistry () @interface DoricRegistry ()
@ -68,6 +69,7 @@ - (void)innerRegister {
[self registerNativePlugin:DoricStoragePlugin.class withName:@"storage"]; [self registerNativePlugin:DoricStoragePlugin.class withName:@"storage"];
[self registerNativePlugin:DoricNavigatorPlugin.class withName:@"navigator"]; [self registerNativePlugin:DoricNavigatorPlugin.class withName:@"navigator"];
[self registerNativePlugin:DoricNavBarPlugin.class withName:@"navbar"]; [self registerNativePlugin:DoricNavBarPlugin.class withName:@"navbar"];
[self registerNativePlugin:DoricPopoverPlugin.class withName:@"popover"];
[self registerViewNode:DoricStackNode.class withName:@"Stack"]; [self registerViewNode:DoricStackNode.class withName:@"Stack"];
[self registerViewNode:DoricVLayoutNode.class withName:@"VLayout"]; [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; __weak typeof(self) _self = self;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(_self) self = _self; __strong typeof(_self) self = _self;
[self.doricContext.rootNode also:^(DoricRootNode *it) {
it.viewId = argument[@"id"]; NSString *viewId = argument[@"id"];
[it render:argument[@"props"]];
}]; 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; DoricViewNode *viewNode = nil;
for (NSString *viewId in viewIds) { for (NSString *viewId in viewIds) {
if (!viewNode) { if (!viewNode) {
viewNode = self.doricContext.rootNode; viewNode = [self.doricContext targetViewNode:viewId];
} else { } else {
if ([viewNode isKindOfClass:[DoricSuperNode class]]) { if ([viewNode isKindOfClass:[DoricSuperNode class]]) {
viewNode = [((DoricSuperNode *) viewNode) subNodeWithViewId:viewId]; viewNode = [((DoricSuperNode *) viewNode) subNodeWithViewId:viewId];

View File

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

View File

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

View File

@ -24,7 +24,6 @@
#import "DoricLayouts.h" #import "DoricLayouts.h"
#import "UIView+Doric.h" #import "UIView+Doric.h"
NS_ASSUME_NONNULL_BEGIN
@class DoricSuperNode; @class DoricSuperNode;
@interface DoricViewNode <V:UIView *> : DoricContextHolder @interface DoricViewNode <V:UIView *> : DoricContextHolder
@ -55,5 +54,3 @@ NS_ASSUME_NONNULL_BEGIN
- (void)requestLayout; - (void)requestLayout;
@end @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"]) { } else if ([name isEqualToString:@"layoutConfig"]) {
if (self.superNode && [prop isKindOfClass:[NSDictionary class]]) { if (self.superNode && [prop isKindOfClass:[NSDictionary class]]) {
[self.superNode blendSubNode:self layoutConfig:prop]; [self.superNode blendSubNode:self layoutConfig:prop];
} else {
[self blendLayoutConfig:prop];
} }
} else if ([name isEqualToString:@"onClick"]) { } else if ([name isEqualToString:@"onClick"]) {
self.callbackIds[@"onClick"] = prop; self.callbackIds[@"onClick"] = prop;
@ -246,4 +248,36 @@ - (NSNumber *)getRotation {
return @(degree); 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 @end

View File

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

View File

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