OpenCAX/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.cpp

624 lines
27 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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