624 lines
27 KiB
C++
624 lines
27 KiB
C++
#include "NativeMgr.h"
|
||
#include <ace/xcomponent/native_interface_xcomponent.h>
|
||
#include <cstdint>
|
||
#include <cstdio>
|
||
#include <hilog/log.h>
|
||
#include <string>
|
||
#include "arkui/native_node.h"
|
||
#include "arkui/native_node_napi.h"
|
||
#include "arkui/native_interface.h"
|
||
#include "common.h"
|
||
#include <random>
|
||
#include <map>
|
||
#include <iostream>
|
||
#define COLUMN_MARGIN 10
|
||
#define XC_WIDTH 800
|
||
#define XC_HEIGHT 600
|
||
#define ARG_CNT 2
|
||
#ifndef NATIVE_TAG
|
||
#define NATIVE_TAG "NativeMgr"
|
||
#endif
|
||
#include "arkui/ui_input_event.h"
|
||
|
||
namespace NativeOpenCAX {
|
||
// [Start plugin_manager_cpp]
|
||
// plugin_manager.cpp
|
||
std::unordered_map<std::string, ArkUI_NodeHandle> NativeMgr::nodeHandleMap_;
|
||
std::unordered_map<void *, OH_ArkUI_SurfaceCallback *> NativeMgr::callbackMap_;
|
||
ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
|
||
// [StartExclude plugin_manager_cpp]
|
||
OH_NativeXComponent_Callback NativeMgr::xSurfaceTouchEventCallBack;
|
||
OH_NativeXComponent_MouseEvent_Callback NativeMgr::xMouseEventCallBack;
|
||
|
||
std::string NativeMgr::crtXCompId;
|
||
NativeMgr NativeMgr::pluginManager_;
|
||
OCCTMgr OCCTMgr::occtMgr;
|
||
std::unordered_map<std::string,NXInfo*> NativeMgr::NxInfos;
|
||
int32_t NativeMgr::hasDraw_ = 0;
|
||
int32_t NativeMgr::hasChangeColor_ = 0;
|
||
|
||
static std::mutex mapMutex;
|
||
|
||
std::string uuid_v4() {
|
||
// 使用当前时间戳和随机数生成UUID
|
||
auto timestamp = std::chrono::high_resolution_clock::now().time_since_epoch().count();
|
||
std::random_device rd;
|
||
std::mt19937_64 gen(rd());
|
||
std::uniform_int_distribution<uint64_t> dis(0, std::numeric_limits<uint64_t>::max());
|
||
uint64_t random_part = dis(gen);
|
||
|
||
// 合并时间戳和随机数,并转换为UUID格式
|
||
uint64_t full_uuid = (timestamp << 32) | (random_part & 0xFFFFFFFF);
|
||
std::stringstream ss;
|
||
ss << std::hex << std::uppercase << std::setw(8) << std::setfill('0') << (full_uuid & 0xFFFFFFFF)
|
||
<< "-" << std::setw(4) << std::setfill('0') << (full_uuid >> 32 & 0xFFFF)
|
||
<< "-4" // UUID版本4,中间四位固定为04xx
|
||
<< std::setw(3) << std::setfill('0') << (random_part >> 48 & 0x0FFF | 0x4000) // 设置版本号和一些随机位
|
||
<< "-" << std::setw(4) << std::setfill('0') << (random_part >> 32 & 0xFFFF)
|
||
<< "-" << std::setw(12) << std::setfill('0') << (random_part & 0xFFFFFFFFFFFF);
|
||
return ss.str();
|
||
}
|
||
|
||
NativeMgr::~NativeMgr() {
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "~NativeMgr");
|
||
nativeXComponentMap_.clear();
|
||
std::lock_guard<std::mutex> lock(mapMutex);
|
||
OCCTMgr::GetInstance()->destroy(crtXCompId);
|
||
for (auto iter = pluginManagerMap_.begin(); iter != pluginManagerMap_.end(); ++iter) {
|
||
if (iter->second != nullptr) {
|
||
delete iter->second;
|
||
iter->second = nullptr;
|
||
}
|
||
}
|
||
pluginManagerMap_.clear();
|
||
}
|
||
|
||
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
|
||
// [StartExclude plugin_on_surface_created]
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceCreatedCB");
|
||
//主动关闭CPU访问窗口缓冲区数据降低功耗
|
||
uint64_t usage = 0;
|
||
int32_t ret2 = OH_NativeWindow_NativeWindowHandleOpt((OHNativeWindow*)window, SET_USAGE, usage);
|
||
|
||
int32_t ret;
|
||
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
|
||
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
|
||
ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
|
||
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||
return;
|
||
}
|
||
|
||
std::string id(idStr);
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceCreatedCB id=%{public}s",
|
||
id.c_str());
|
||
// [EndExclude plugin_on_surface_created]
|
||
// 初始化环境与绘制背景
|
||
auto *pluginManger = NativeMgr::GetInstance();
|
||
pluginManger->OnSurfaceCreated(component, window);
|
||
|
||
}
|
||
void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) {
|
||
// [StartExclude plugin_on_surface_changed]
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceChangedCB");
|
||
int32_t ret;
|
||
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
|
||
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
|
||
ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
|
||
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||
return;
|
||
}
|
||
std::string id(idStr);
|
||
// [EndExclude plugin_on_surface_changed]
|
||
auto *pluginManger = NativeMgr::GetInstance();
|
||
// 封装OnSurfaceChanged方法
|
||
pluginManger->OnSurfaceChanged(component, window);
|
||
}
|
||
void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) {
|
||
// [StartExclude plugin_on_surface_destroyed]
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB");
|
||
int32_t ret;
|
||
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
|
||
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
|
||
ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
|
||
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||
return;
|
||
}
|
||
std::string id(idStr);
|
||
// [EndExclude plugin_on_surface_destroyed]
|
||
auto *pluginManger = NativeMgr::GetInstance();
|
||
pluginManger->OnSurfaceDestroyed(component, window);
|
||
}
|
||
//NativeMgr回调
|
||
void NativeMgr::OnSurfaceCreated(OH_NativeXComponent *component, void *window) {
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceCreated");
|
||
if (!window) {
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native",
|
||
"ERROR: window is NULL in OnSurfaceCreated!");
|
||
return;
|
||
}
|
||
|
||
OH_NativeXComponent_GetXComponentSize(component, window, &bfWidth, &bfHeight);
|
||
std::lock_guard<std::mutex> lock(mapMutex);
|
||
if(!OCCTMgr::GetInstance()->findRenderThread(crtXCompId)){
|
||
HILOG_ERROR(NATIVE_TAG,"uint64_t bfSize:%{public}dX%{public}d",bfWidth,bfHeight);
|
||
OCCTMgr::GetInstance()->initOCCTMgr();
|
||
}
|
||
OCCTMgr::GetInstance()->createReaderThread(crtXCompId, bfWidth, bfHeight, reinterpret_cast<OHNativeWindow*>(window));
|
||
}
|
||
void NativeMgr::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window) {
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceDestroyed");
|
||
{
|
||
std::lock_guard<std::mutex> lock(mapMutex);
|
||
OCCTMgr::GetInstance()->destroy(crtXCompId);
|
||
}
|
||
}
|
||
void NativeMgr::OnSurfaceChanged(OH_NativeXComponent *component, void *window) {
|
||
OH_NativeXComponent_GetXComponentSize(component, window, &afWidth, &afHeight);
|
||
{
|
||
if(bfWidth==afWidth && bfHeight==afHeight){
|
||
return;
|
||
}
|
||
std::lock_guard<std::mutex> lock(mapMutex);
|
||
if (OCCTMgr::GetInstance()->findRenderThread(crtXCompId)) {
|
||
HILOG_ERROR(NATIVE_TAG,"uint64_t Size:%{public}dX%{public}d",bfWidth,bfHeight);
|
||
bfWidth=afWidth;
|
||
bfHeight=afHeight;
|
||
auto renderThread=OCCTMgr::GetInstance()->getRenderThread(crtXCompId);
|
||
if(renderThread!=nullptr){
|
||
renderThread->resizeWindow(bfWidth, bfHeight);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
void OnMouseEventCB(OH_NativeXComponent* component, void* window) {
|
||
auto* pluginManager = NativeMgr::GetInstance();
|
||
if (!pluginManager || !window) {
|
||
return;
|
||
}
|
||
auto *pluginManger = NativeMgr::GetInstance();
|
||
pluginManger->OnMouseEvent(component, window);
|
||
}
|
||
void NativeMgr::OnMouseEvent(OH_NativeXComponent *comp, void *win) {
|
||
int32_t ret;
|
||
OH_NativeXComponent_MouseEvent mouseEvent;
|
||
ret = OH_NativeXComponent_GetMouseEvent(comp, win, &mouseEvent);
|
||
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||
return;
|
||
}
|
||
OH_NativeXComponent_ExtraMouseEventInfo* extra = NULL;
|
||
|
||
ret = OH_NativeXComponent_GetExtraMouseEventInfo(comp, &extra);
|
||
|
||
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||
return;
|
||
}
|
||
//Test Mouse MIDDLE_BUTTON Long Press
|
||
HILOG_WARN(NATIVE_TAG, "ExtraMouseEventInfo:%{public}d",extra);
|
||
std::lock_guard<std::mutex> lock(mapMutex);
|
||
//通过时间戳判断事件唯一性.保证单一时间戳只触发一次事件
|
||
if(mouseEvent.timestamp==NativeMgr::timestamp){
|
||
return;
|
||
}
|
||
NativeMgr::timestamp=mouseEvent.timestamp;
|
||
auto renderThread=OCCTMgr::GetInstance()->getRenderThread(crtXCompId);
|
||
if(renderThread==nullptr){
|
||
HILOG_WARN(NATIVE_TAG, "Render thread not found for rotation.");
|
||
return;
|
||
}
|
||
|
||
float curtX,curtY;
|
||
//开发测试模拟器输出鼠标按钮和时间类型,时间戳
|
||
bool _log=true;
|
||
if(_log){
|
||
HILOG_INFO(NATIVE_TAG, "ALLButton:%{public}d",mouseEvent.button);
|
||
HILOG_INFO(NATIVE_TAG, "ALLAction:%{public}d",mouseEvent.action);
|
||
HILOG_INFO(NATIVE_TAG, "ALLTimestamp:%{public}d",mouseEvent.timestamp);
|
||
}
|
||
//鼠标滚轮缩放实现
|
||
|
||
//以下代码为采用按住鼠标右键不放进行Move改变Carmera的旋转视角
|
||
//旋转视角分为三种模式:
|
||
//自由模式.基于世界坐标系0,0,0
|
||
//模型中心.通过边界盒计算模型的中心点,进行旋转
|
||
//基于鼠标按下右键点进行旋转
|
||
|
||
//按住Ctrl不放同时按住鼠标左键不放进行Carmera的移动
|
||
//移动模式:均为鼠标点按下后记录坐标增量移动
|
||
|
||
|
||
//鼠标按下并且事件为鼠标中键
|
||
if(mouseEvent.button==OH_NATIVEXCOMPONENT_LEFT_BUTTON&&mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_PRESS){
|
||
if(NativeMgr::isMouseMiddleBtnPressed){
|
||
NativeMgr::isMouseMiddleBtnPressed=false;
|
||
return;
|
||
}
|
||
//记录按下时候的X.Y坐标
|
||
NativeMgr::lastMouseX_=mouseEvent.x;
|
||
NativeMgr::lastMouseY_=mouseEvent.y;
|
||
NativeMgr::isMouseMiddleBtnPressed = true;
|
||
//HILOG_WARN(NATIVE_TAG, "AtlastMouseX:%{public}d",NativeMgr::lastMouseX_);
|
||
//HILOG_WARN(NATIVE_TAG, "AtlastMouseY:%{public}d",NativeMgr::lastMouseY_);
|
||
//HILOG_WARN(NATIVE_TAG, "AtButton:%{public}d",mouseEvent.button);
|
||
//HILOG_WARN(NATIVE_TAG, "AtButtonAction:%{public}d",mouseEvent.action);
|
||
//HILOG_WARN(NATIVE_TAG, "AtisMouseMiddleBtnPressed:%{public}d",NativeMgr::isMouseMiddleBtnPressed);
|
||
}else if(mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_MOVE&&NativeMgr::isMouseMiddleBtnPressed){
|
||
// 计算鼠标移动距离
|
||
float deltaX = curtX - NativeMgr::lastMouseX_;
|
||
float deltaY = curtY - NativeMgr::lastMouseY_;
|
||
// 将像素移动量映射到旋转角度
|
||
// 这里的系数可以根据需要调整灵敏度
|
||
float rotationSpeed = 0.001f;
|
||
float angleX = deltaX * rotationSpeed;
|
||
float angleY = deltaY * rotationSpeed;
|
||
// 通知渲染线程执行旋转
|
||
// 由于渲染在线程里,需要通过命令队列发送指令
|
||
renderThread->setRotation(angleX, angleY);
|
||
// 更新最后的位置
|
||
//NativeMgr::lastMouseX_ = deltaX;
|
||
//NativeMgr::lastMouseY_ = deltaY;
|
||
//HILOG_WARN(NATIVE_TAG, "MoveAngleX:%{public}d",angleX);
|
||
//HILOG_WARN(NATIVE_TAG, "MoveAngleY:%{public}d",angleY);
|
||
//HILOG_WARN(NATIVE_TAG, "MoveButton:%{public}d",mouseEvent.button);
|
||
//HILOG_WARN(NATIVE_TAG, "MoveButtonAction:%{public}d",mouseEvent.action);
|
||
//HILOG_WARN(NATIVE_TAG, "MoveIsMouseMiddleBtnPressed:%{public}d",NativeMgr::isMouseMiddleBtnPressed);
|
||
}
|
||
|
||
}
|
||
static std::string value2String(napi_env env, napi_value value) {
|
||
size_t stringSize = 0;
|
||
napi_get_value_string_utf8(env, value, nullptr, 0, &stringSize);
|
||
std::string valueString;
|
||
valueString.resize(stringSize);
|
||
napi_get_value_string_utf8(env, value, &valueString[0], stringSize + 1, &stringSize);
|
||
return valueString;
|
||
}
|
||
|
||
void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
|
||
{
|
||
// [StartExclude plugin_dispatch_touch_event]
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB");
|
||
int32_t ret;
|
||
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
|
||
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
|
||
ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
|
||
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||
return;
|
||
}
|
||
std::string id(idStr);
|
||
// [EndExclude plugin_dispatch_touch_event]
|
||
auto *pluginManger = NativeMgr::GetInstance();
|
||
pluginManger->DispatchTouchEvent(component, window);
|
||
}
|
||
|
||
// XComponent回调事件
|
||
NativeMgr::NativeMgr() {
|
||
xSurfaceTouchEventCallBack.OnSurfaceCreated = OnSurfaceCreatedCB;
|
||
xSurfaceTouchEventCallBack.OnSurfaceChanged = OnSurfaceChangedCB;
|
||
xSurfaceTouchEventCallBack.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
|
||
xSurfaceTouchEventCallBack.DispatchTouchEvent=DispatchTouchEventCB;
|
||
xMouseEventCallBack.DispatchMouseEvent= OnMouseEventCB;
|
||
}
|
||
// 创建节点组件
|
||
ArkUI_NodeHandle CreateNodeHandle(void* userData) {
|
||
auto ud=static_cast<NXInfo*>(userData);
|
||
HILOG_INFO(NATIVE_TAG,"CreateNodeHandle NODE ID:%{public}s",ud->nid.c_str());
|
||
HILOG_INFO(NATIVE_TAG,"CreateNodeHandle XCOMP ID:%{public}s",ud->xid.c_str());
|
||
// 创建Node也名创建ROW Column等容器
|
||
ArkUI_NodeHandle nodeHandel = nodeAPI->createNode(ARKUI_NODE_RELATIVE_CONTAINER);
|
||
// 节点默认宽度or高度
|
||
ArkUI_NumberValue nodeMarginData[] = {{.u32 = 0}, {.f32 = 0}};
|
||
// ArkUI_AttributeItem
|
||
// 参数1:指向数值数组
|
||
// 参数2:数组元素个数
|
||
// 参数3:属性名(可隐藏)
|
||
ArkUI_AttributeItem nodeMarginItem = {nodeMarginData};
|
||
// 设置Node宽度or高度
|
||
nodeAPI->setAttribute(nodeHandel, NODE_MARGIN, &nodeMarginItem);
|
||
NativeMgr::nodeHandleMap_[ud->nid]=nodeHandel;
|
||
// 创建XComponent组件
|
||
// 组件类型Item
|
||
ArkUI_NumberValue comTypeData[] = {ARKUI_XCOMPONENT_TYPE_SURFACE};
|
||
ArkUI_AttributeItem comTypeItem = {comTypeData};
|
||
// 组件ID Item
|
||
ArkUI_AttributeItem comIdItem = {.string = ud->xid.c_str()};
|
||
// 组件Surface Size
|
||
// 创建组件
|
||
ArkUI_NodeHandle xc;
|
||
xc = nodeAPI->createNode(ARKUI_NODE_XCOMPONENT);
|
||
// 设置XComponent组件属性
|
||
nodeAPI->setAttribute(xc, NODE_XCOMPONENT_TYPE, &comTypeItem);
|
||
nodeAPI->setAttribute(xc, NODE_XCOMPONENT_ID, &comIdItem);
|
||
|
||
// 焦点设置
|
||
ArkUI_NumberValue focusable[] = {1};
|
||
focusable[0].i32 = 1;
|
||
ArkUI_AttributeItem focusableItem = {focusable};
|
||
nodeAPI->setAttribute(xc, NODE_FOCUSABLE, &focusableItem);
|
||
// 节点ID
|
||
ArkUI_AttributeItem nodeIdItem = {.string = ud->nid.c_str()};
|
||
nodeAPI->setAttribute(xc, NODE_ID, &nodeIdItem);
|
||
|
||
auto *nativeXComponent = OH_NativeXComponent_GetNativeXComponent(xc);
|
||
if (!nativeXComponent) {
|
||
HILOG_ERROR(NATIVE_TAG,"GetNativeXComponent error");
|
||
return nodeHandel;
|
||
}
|
||
// 注册XComponent回调函数
|
||
OH_NativeXComponent_RegisterCallback(nativeXComponent, &NativeMgr::xSurfaceTouchEventCallBack);
|
||
//注册XComponent组件鼠标回调事件
|
||
OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &NativeMgr::xMouseEventCallBack);
|
||
// nodeAPI->registerNodeEvent(xc, NODE_ON_MOUSE, 1, &xc);
|
||
// nodeAPI->registerNodeEvent(xc, NODE_ON_AXIS, 1, &xc);
|
||
// nodeAPI->addNodeEventReceiver(xc, [](ArkUI_NodeEvent *event) {
|
||
// auto *inputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event);
|
||
// auto eventType = OH_ArkUI_UIInputEvent_GetType(inputEvent);
|
||
// if (OH_ArkUI_NodeEvent_GetEventType(event) == NODE_ON_AXIS ) {
|
||
// HILOG_WARN(NATIVE_TAG, "NODE_ON_AXIS:%{public}d",OH_ArkUI_NodeEvent_GetEventType(event));
|
||
// }
|
||
// if (eventType == ARKUI_UIINPUTEVENT_TYPE_MOUSE) {
|
||
// auto action = OH_ArkUI_MouseEvent_GetMouseAction(inputEvent);
|
||
// auto button= OH_ArkUI_MouseEvent_GetMouseButton(inputEvent);
|
||
// //HILOG_WARN(NATIVE_TAG, "MouseAction:%{public}d",action);
|
||
// //HILOG_WARN(NATIVE_TAG, "MouseButton:%{public}d",button);
|
||
//
|
||
// int32_t buttonArray[10];
|
||
// int32_t arraySize = sizeof(buttonArray) / sizeof(buttonArray[0]);
|
||
// int32_t actualCount = arraySize; // 将数组大小存入actualCount,作为输入值
|
||
// int32_t ret = OH_ArkUI_MouseEvent_GetPressedButtons(inputEvent, buttonArray, &actualCount);
|
||
//
|
||
// // --- 步骤 3: 检查API调用结果 ---
|
||
// if (ret != 0) {
|
||
// HILOG_WARN(NATIVE_TAG, "Error getting pressed mouse buttons. Error code: %{public}d\n", ret);
|
||
// return;
|
||
// }
|
||
// for (int i = 0; i < actualCount; ++i) {
|
||
// HILOG_WARN(NATIVE_TAG, "Curt code: %{public}d\n", buttonArray[i]);
|
||
// // 根据常见的鼠标按钮ID进行解释 (具体ID定义请查阅官方文档)
|
||
// // 通常 1=主按钮(左键), 2=辅助按钮(右键), 3=中间按钮(滚轮)
|
||
// switch (buttonArray[i]) {
|
||
// case 1: HILOG_WARN(NATIVE_TAG, "MouseButton:Left");break;
|
||
// case 2: HILOG_WARN(NATIVE_TAG, "MouseButton:Right");break;
|
||
// case 3: HILOG_WARN(NATIVE_TAG, "MouseButton:Middle"); break;
|
||
// default: printf("(Other_%d) ", buttonArray[i]); break;
|
||
// }
|
||
// }
|
||
// }
|
||
// });
|
||
// 组件类型
|
||
auto comTypeRet = nodeAPI->getAttribute(xc, NODE_XCOMPONENT_TYPE);
|
||
HILOG_INFO(NATIVE_TAG,"XCom type: %{public}d",comTypeRet->value[0].i32);
|
||
// 组件ID
|
||
auto comIdRet = nodeAPI->getAttribute(xc, NODE_XCOMPONENT_ID);
|
||
HILOG_INFO(NATIVE_TAG,"XCom ID: %{public}d",comIdRet->string);
|
||
// 增加组件到节点
|
||
nodeAPI->addChild(nodeHandel, xc);
|
||
return nodeHandel;
|
||
|
||
}
|
||
// Native侧创建Node
|
||
napi_value NativeMgr::initNativeNode(napi_env env, napi_callback_info info) {
|
||
if ((env == nullptr) || (info == nullptr)) {
|
||
HILOG_ERROR(NATIVE_TAG,"CreateNativeNode env or info is null");
|
||
return nullptr;
|
||
}
|
||
//获取传入NodeContent实例
|
||
size_t argCnt = 4;
|
||
napi_value args[4] = {nullptr};
|
||
if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
|
||
HILOG_ERROR(NATIVE_TAG,"CreateNativeNode napi_get_cb_info failed");
|
||
}
|
||
|
||
bool type;
|
||
NXInfo* nxInfo=new NXInfo;
|
||
nxInfo->nid=value2String(env, args[0]);
|
||
nxInfo->xid=value2String(env, args[1]);
|
||
napi_get_value_bool(env, args[2], &type);
|
||
|
||
crtXCompId=nxInfo->xid;
|
||
NxInfos[nxInfo->xid]=nxInfo;
|
||
ArkUI_NodeContentHandle _nodeContentHandle = nullptr;
|
||
// 获取ArkTS侧创建的NodeContent对象,映射到Native侧的
|
||
OH_ArkUI_GetNodeContentFromNapiValue(env, args[3], &_nodeContentHandle);
|
||
// 查询指定的模块接口名
|
||
nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
|
||
//下面的代码主要用于创建一个Native侧和arkui侧绑定数据的结构传递传输的操作
|
||
//node_data可以理解为一个结构体等等之类的指针
|
||
// 生成节点名采用NODE_ID_+UUID
|
||
HILOG_INFO(NATIVE_TAG,"Native NODE ID:%{public}s",nxInfo->nid.c_str());
|
||
HILOG_INFO(NATIVE_TAG,"Native XCOMP ID:%{public}s",nxInfo->xid.c_str());
|
||
// 在NodeContent对象上保存自定义数据。
|
||
int32_t ret = OH_ArkUI_NodeContent_SetUserData(_nodeContentHandle, static_cast<void*>(nxInfo));
|
||
if (ret != ARKUI_ERROR_CODE_NO_ERROR) {
|
||
HILOG_ERROR(NATIVE_TAG,"setUserData failed error=%{public}d",ret);
|
||
}
|
||
if (nodeAPI != nullptr && nodeAPI->createNode != nullptr && nodeAPI->addChild != nullptr) {
|
||
auto nodeContentEvent = [](ArkUI_NodeContentEvent *event) {
|
||
// 获取Node连接事件的对应Node的Handle
|
||
ArkUI_NodeContentHandle handle = OH_ArkUI_NodeContentEvent_GetNodeContentHandle(event);
|
||
// 获取对应Handle的UserData
|
||
void* ud=OH_ArkUI_NodeContent_GetUserData(handle);
|
||
if (OH_ArkUI_NodeContentEvent_GetEventType(event) == NODE_CONTENT_EVENT_ON_ATTACH_TO_WINDOW) {
|
||
ArkUI_NodeHandle testNode;
|
||
if (ud) {
|
||
testNode = CreateNodeHandle(ud);
|
||
delete ud;
|
||
ud = nullptr;
|
||
} else {
|
||
//testNode = CreateNodeHandle(nullptr);
|
||
}
|
||
// 向NodeContent中添加子组件
|
||
OH_ArkUI_NodeContent_AddNode(handle, testNode);
|
||
}
|
||
};
|
||
OH_ArkUI_NodeContent_RegisterCallback(_nodeContentHandle, nodeContentEvent);
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
void NativeMgr::DispatchTouchEvent(OH_NativeXComponent* component, void* window)
|
||
{
|
||
OH_NativeXComponent_TouchEvent touchEvent_;
|
||
int32_t ret = OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent_);
|
||
std::lock_guard<std::mutex> lock(mapMutex);
|
||
//通过时间戳判断事件唯一性.保证单一时间戳只触发一次事件
|
||
if(touchEvent_.timeStamp==NativeMgr::timestamp){
|
||
return;
|
||
}
|
||
NativeMgr::timestamp=touchEvent_.timeStamp;
|
||
auto renderThread=OCCTMgr::GetInstance()->getRenderThread(crtXCompId);
|
||
if(renderThread==nullptr){
|
||
HILOG_WARN(NATIVE_TAG, "Render thread not found for rotation.");
|
||
return;
|
||
}
|
||
if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||
float tiltX = 2.2;
|
||
float tiltY = 2.2;
|
||
OH_NativeXComponent_TouchPointToolType toolType =
|
||
OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS;
|
||
OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType);
|
||
OH_NativeXComponent_GetTouchPointTiltX(component, 0, &tiltX);
|
||
OH_NativeXComponent_GetTouchPointTiltY(component, 0, &tiltY);
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native",
|
||
"Touch Info : x=%{public}f, y=%{public}f screenx=%{public}f, screeny=%{public}f,"
|
||
"type=%{public}d, force=%{public}f, tiltX=%{public}f, tiltY=%{public}f, toolType=%{public}d",
|
||
touchEvent_.x, touchEvent_.y, touchEvent_.screenX,
|
||
touchEvent_.screenY, touchEvent_.type, touchEvent_.force, tiltX, tiltY, toolType);
|
||
//判断触控点数量
|
||
//当触点为1则判定为单指,处理单指对应事件
|
||
if(touchEvent_.numPoints==1){
|
||
//触屏按下记录按下点坐标
|
||
if(touchEvent_.type ==OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_DOWN){
|
||
NativeMgr::x=touchEvent_.x;
|
||
NativeMgr::y=touchEvent_.y;
|
||
}
|
||
//按下并移动,计算移动增量需要乘以灵敏度
|
||
if (touchEvent_.type == OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_MOVE) {
|
||
float dtx=(NativeMgr::x-touchEvent_.x)*0.1;
|
||
float dty=(NativeMgr::y-touchEvent_.y)*0.1;
|
||
renderThread->setRotation(dtx, dty);
|
||
OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent_);
|
||
NativeMgr::x=touchEvent_.x;
|
||
NativeMgr::y=touchEvent_.y;
|
||
}
|
||
//的判断为双指,处理双指事件功能(缩放视距)
|
||
}
|
||
else if(touchEvent_.numPoints==2)
|
||
{
|
||
//双指同时处于按下状态,并且移动
|
||
if(touchEvent_.touchPoints[0].isPressed
|
||
&&touchEvent_.touchPoints[1].isPressed){
|
||
//当双指按下时候,分别记录每个指的坐标
|
||
|
||
//双指移动,计算移动位移量,同时根据移动缩放因子计算视距,从调整相机相对于模型的距离.从而实现双指缩放
|
||
}else if(touchEvent_.type==OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_MOVE){
|
||
|
||
}
|
||
}
|
||
} else {
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "touch fail");
|
||
}
|
||
|
||
int32_t size = 0;
|
||
OH_NativeXComponent_HistoricalPoint *points = nullptr;
|
||
|
||
if (OH_NativeXComponent_GetHistoricalPoints(component, window, &size, &points) ==
|
||
OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "XComponent_Native", "HistoricalPoints size=%{public}d",
|
||
size);
|
||
for (auto i = 0; i < size; i++) {
|
||
auto point = points[i];
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "XComponent_Native",
|
||
"HistoricalPoint %{public}d Info : id=%{public}d, x=%{public}f, y=%{public}f, "
|
||
"type=%{public}d, timeStamp=%{public}lld, sourceTool=%{public}d",
|
||
i, point.id, point.x, point.y, point.type, point.timeStamp, point.sourceTool);
|
||
}
|
||
}
|
||
}
|
||
//设置期望帧率
|
||
napi_value NativeMgr::SetFrameRate(napi_env env, napi_callback_info info) {
|
||
size_t argc = 4;
|
||
napi_value args[4] = {nullptr};
|
||
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||
std::string nodeId = value2String(env, args[0]);
|
||
auto node = nodeHandleMap_[nodeId];
|
||
|
||
int32_t min = 0;
|
||
napi_get_value_int32(env, args[FIRST_ARG], &min);
|
||
|
||
int32_t max = 0;
|
||
napi_get_value_int32(env, args[SECOND_ARG], &max);
|
||
|
||
int32_t expected = 0;
|
||
napi_get_value_int32(env, args[THIRD_ARG], &expected);
|
||
OH_NativeXComponent_ExpectedRateRange range = {.min = min, .max = max, .expected = expected};
|
||
OH_ArkUI_XComponent_SetExpectedFrameRateRange(node, range); // 设置期望帧率
|
||
return nullptr;
|
||
}
|
||
napi_value NativeMgr::SetNeedSoftKeyboard(napi_env env, napi_callback_info info) {
|
||
size_t argc = 2;
|
||
napi_value args[2] = {nullptr};
|
||
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||
std::string nodeId = value2String(env, args[0]);
|
||
ArkUI_NodeHandle node;
|
||
if (nodeHandleMap_.find(nodeId) == nodeHandleMap_.end()) {
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "SetNeedSoftKeyboard", "nodeId not exit error");
|
||
return nullptr;
|
||
}
|
||
node = nodeHandleMap_[nodeId];
|
||
|
||
bool needSoftKeyboard = false;
|
||
napi_get_value_bool(env, args[1], &needSoftKeyboard);
|
||
OH_ArkUI_XComponent_SetNeedSoftKeyboard(node, needSoftKeyboard); // 设置是否需要软键盘
|
||
return nullptr;
|
||
}
|
||
napi_value NativeMgr::NapiLoadModel(napi_env env, napi_callback_info info) {
|
||
size_t argc = 1;
|
||
napi_value args[1];
|
||
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||
std::string path = value2String(env, args[0]);
|
||
{
|
||
std::lock_guard<std::mutex> lock(mapMutex);
|
||
|
||
auto renderThread=OCCTMgr::GetInstance()->getRenderThread(crtXCompId);
|
||
if(renderThread==nullptr){
|
||
HILOG_WARN(NATIVE_TAG, "Render thread not found for rotation.");
|
||
}else{
|
||
renderThread->loadModel(std::string(path));
|
||
}
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
//切换视图
|
||
napi_value NativeMgr::SwitchView(napi_env env, napi_callback_info info){
|
||
size_t argc = 1;
|
||
napi_value args[1];
|
||
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||
std::string viewName = value2String(env, args[0]);
|
||
{
|
||
std::lock_guard<std::mutex> lock(mapMutex);
|
||
auto renderThread=OCCTMgr::GetInstance()->getRenderThread(crtXCompId);
|
||
if(renderThread==nullptr){
|
||
HILOG_WARN(NATIVE_TAG, "Render thread not found for rotation.");
|
||
}else{
|
||
renderThread->swicthView(viewName);
|
||
}
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
//显示模型边界
|
||
napi_value NativeMgr::displayModelEdges(napi_env env, napi_callback_info info){
|
||
|
||
}
|
||
//显示模型线框
|
||
napi_value NativeMgr::displayHLR(napi_env env, napi_callback_info info){
|
||
|
||
}
|
||
//显示隐藏线
|
||
napi_value NativeMgr::displayHL(napi_env env, napi_callback_info info){
|
||
|
||
}
|
||
|
||
} // namespace NativeOpenCAX
|