重构布局.独立文件菜单.

应用模块独立为公共模块.方便模块切换.
未开发:需要对装饰器重新定义.
This commit is contained in:
JackLee 2026-03-05 17:17:40 +08:00
parent 8b9dbff0ee
commit 6e51b8ba36
14 changed files with 199 additions and 210 deletions

View File

@ -1,14 +1,19 @@
#include "EGLCore.h"
#include <cstdio>
#include "NativeEGLOCCT/common.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "EGLCore"
#endif
namespace NativeOpenCAX {
EGLCore::EGLCore()
: eglDisplay_(EGL_NO_DISPLAY),
eglContext_(EGL_NO_CONTEXT),
eglSurface_(EGL_NO_SURFACE),
nativeWindow_(nullptr) {}
: eglDisplay(EGL_NO_DISPLAY),
eglContext(EGL_NO_CONTEXT),
eglSurface(EGL_NO_SURFACE),
nativeWindow(nullptr)
{
}
EGLCore::~EGLCore() {
destroy();
@ -19,25 +24,24 @@ bool EGLCore::init(OHNativeWindow* window) {
printf("Native window is null\n");
return false;
}
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore","Current Thread ID: %{public}d",std::this_thread::get_id());
nativeWindow_ = window;
nativeWindow=window;
HILOG_INFO(NATIVE_TAG,"Current Thread ID: %{public}d",std::this_thread::get_id());
// 获取EGL display
eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (eglDisplay_ == EGL_NO_DISPLAY) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","eglGetDisplay failed:%{public}d",std::this_thread::get_id());
eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (eglDisplay == EGL_NO_DISPLAY) {
HILOG_ERROR(NATIVE_TAG,"eglGetDisplay failed:%{public}d",glGetError());
return false;
}
// 初始化EGL
EGLint majorVersion;
EGLint minorVersion;
if (!eglInitialize(eglDisplay_, &majorVersion, &minorVersion)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","eglInitialize failed:%{public}d",std::this_thread::get_id());
if (!eglInitialize(eglDisplay, &majorVersion, &minorVersion)) {
HILOG_ERROR(NATIVE_TAG,"eglInitialize failed:%{public}d",glGetError());
return false;
}
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","EGLDisplay version:%{public}d",majorVersion+"."+minorVersion);
HILOG_ERROR(NATIVE_TAG,"EGLDisplay version:%{public}d%{public}d",majorVersion,minorVersion);
// 配置EGL
EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@ -53,14 +57,15 @@ bool EGLCore::init(OHNativeWindow* window) {
const EGLint maxConfigSize = 1;
EGLint numConfigs;
if (!eglChooseConfig(eglDisplay_, attribs, &eglConfig_, maxConfigSize, &numConfigs)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglChooseConfig: unable to choose configs");
if (!eglChooseConfig(eglDisplay, attribs, &eglConfig, maxConfigSize, &numConfigs)) {
HILOG_ERROR(NATIVE_TAG,"eglChooseConfig: unable to choose configs");
return false;
}
// 创建EGL surface
eglSurface_ = eglCreateWindowSurface(eglDisplay_, eglConfig_, (NativeWindowType)nativeWindow_, nullptr);
if (eglSurface_ == EGL_NO_SURFACE) {
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)nativeWindow, nullptr);
if (eglSurface == EGL_NO_SURFACE) {
HILOG_ERROR(NATIVE_TAG,"EGL_NO_SURFACE");
return false;
}
@ -70,8 +75,9 @@ bool EGLCore::init(OHNativeWindow* window) {
EGL_NONE
};
eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, EGL_NO_CONTEXT, contextAttribs);
if (eglContext_ == EGL_NO_CONTEXT) {
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
if (eglContext == EGL_NO_CONTEXT) {
HILOG_ERROR(NATIVE_TAG,"EGL_NO_CONTEXT");
return false;
}
@ -81,38 +87,36 @@ bool EGLCore::init(OHNativeWindow* window) {
// 检查GL错误
GLenum glError = glGetError();
if (glError != GL_NO_ERROR) {
HILOG_ERROR(NATIVE_TAG,"glError:",glError);
return false;
}
// 设置GL视口
glViewport(0, 0, 1280, 720); // 默认大小,实际会随窗口变化
return true;
}
void EGLCore::makeCurrent() {
if (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInitDone","eglMakeCurrent failed: 0x%{public}x\n",eglGetError());
if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
HILOG_ERROR(NATIVE_TAG,"eglMakeCurrent failed: 0x%{public}x\n:",eglGetError());
}
}
bool EGLCore::swapBuffers() {
return eglSwapBuffers(eglDisplay_, eglSurface_);
return eglSwapBuffers(eglDisplay, eglSurface);
}
void EGLCore::destroy() {
if (eglDisplay_ != EGL_NO_DISPLAY) {
if (eglContext_ != EGL_NO_CONTEXT) {
eglDestroyContext(eglDisplay_, eglContext_);
eglContext_ = EGL_NO_CONTEXT;
if (eglDisplay != EGL_NO_DISPLAY) {
if (eglContext != EGL_NO_CONTEXT) {
eglDestroyContext(eglDisplay, eglContext);
eglContext = EGL_NO_CONTEXT;
}
if (eglSurface_ != EGL_NO_SURFACE) {
eglDestroySurface(eglDisplay_, eglSurface_);
eglSurface_ = EGL_NO_SURFACE;
if (eglSurface != EGL_NO_SURFACE) {
eglDestroySurface(eglDisplay, eglSurface);
eglSurface = EGL_NO_SURFACE;
}
eglTerminate(eglDisplay_);
eglDisplay_ = EGL_NO_DISPLAY;
eglTerminate(eglDisplay);
eglDisplay = EGL_NO_DISPLAY;
}
}

View File

@ -28,17 +28,17 @@ public:
void makeCurrent();
bool swapBuffers();
void destroy();
EGLSurface getSurface() const { return eglSurface_; }
EGLContext getContext() const { return eglContext_; }
EGLDisplay getDisplay() const { return eglDisplay_; }
EGLConfig getConfig() const { return eglConfig_; }
OHNativeWindow* getOHNativeWindow()const{return nativeWindow_;}
EGLSurface getSurface() const { return eglSurface; }
EGLContext getContext() const { return eglContext; }
EGLDisplay getDisplay() const { return eglDisplay; }
EGLConfig getConfig() const { return eglConfig; }
OHNativeWindow* getOHNativeWindow()const{return nativeWindow;}
private:
EGLDisplay eglDisplay_;
EGLContext eglContext_;
EGLSurface eglSurface_;
EGLConfig eglConfig_;
OHNativeWindow* nativeWindow_;
EGLDisplay eglDisplay;
EGLContext eglContext;
EGLSurface eglSurface;
EGLConfig eglConfig;
OHNativeWindow* nativeWindow;
};
} // namespace NativeOpenCAX
#endif // EGLCORE_H

View File

@ -29,7 +29,8 @@ ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
// [StartExclude plugin_manager_cpp]
NativeManager NativeManager::pluginManager_;
OH_NativeXComponent_Callback NativeManager::callback_;
OH_NativeXComponent_Callback NativeManager::xSurfaceTouchEventCallBack;
OH_NativeXComponent_MouseEvent_Callback NativeManager::xMouseEventCallBack;
ArkUI_NodeHandle xc;
int32_t NativeManager::hasDraw_ = 0;
int32_t NativeManager::hasChangeColor_ = 0;
@ -216,9 +217,9 @@ static std::string value2String(napi_env env, napi_value value) {
}
// XComponent回调事件
NativeManager::NativeManager() {
callback_.OnSurfaceCreated = OnSurfaceCreatedCB;
callback_.OnSurfaceChanged = OnSurfaceChangedCB;
callback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
xSurfaceTouchEventCallBack.OnSurfaceCreated = OnSurfaceCreatedCB;
xSurfaceTouchEventCallBack.OnSurfaceChanged = OnSurfaceChangedCB;
xSurfaceTouchEventCallBack.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
}
// 创建节点组件
ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
@ -269,7 +270,9 @@ ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
return nodeHandel;
}
// 注册XComponent回调函数
OH_NativeXComponent_RegisterCallback(nativeXComponent, &NativeManager::callback_);
OH_NativeXComponent_RegisterCallback(nativeXComponent, &NativeManager::xSurfaceTouchEventCallBack);
//注册XComponent组件鼠标回调事件
OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &NativeManager::xMouseEventCallBack);
// 组件类型
auto comTypeRet = nodeAPI->getAttribute(xc, NODE_XCOMPONENT_TYPE);
HILOG_INFO(NATIVE_TAG,"XCom type: %{public}d",comTypeRet->value[0].i32);

View File

@ -38,7 +38,9 @@ constexpr const int FRAME_COUNT = 50;
class NativeManager {
public:
static OH_NativeXComponent_Callback callback_;
static OH_NativeXComponent_Callback xSurfaceTouchEventCallBack;
//鼠标事件回调
static OH_NativeXComponent_MouseEvent_Callback xMouseEventCallBack;
NativeManager();
~NativeManager();

View File

@ -1,7 +1,5 @@
#include "NativeRender.h"
#include "Aspect_NeutralWindow.hxx"
#include <GLES3/gl3.h>
#include <cstdio>
#include <cmath>
@ -40,6 +38,7 @@ NativeRender::~NativeRender() {
bool NativeRender::init(int width, int height,EGLCore* eglCore) {
eglCore_=eglCore;
initTextStyle();
initDriver();
initViewer();
initContext();
initView();
@ -49,43 +48,31 @@ bool NativeRender::init(int width, int height,EGLCore* eglCore) {
view_->SetBackgroundColor(clearColor_);
view_->MustBeResized();
view_->RedrawImmediate();
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","NativeRender Init Done");
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","width: %{public}d",width_);
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","height: %{public}d",height_);
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render", "GL Error before render: 0x%{public}x", glGetError());
return true;
}
void NativeRender::initViewer(){
displayPixelRatio();
Handle(Aspect_DisplayConnection) displayConnection=new Aspect_DisplayConnection();
void NativeRender::initDriver() {
// 创建图形驱动
if (graphicDriver_.IsNull()) {
Handle(Aspect_DisplayConnection) displayConnection=new Aspect_DisplayConnection();
graphicDriver_ = new OpenGl_GraphicDriver(displayConnection,Standard_False);
graphicDriver_->ChangeOptions().buffersNoSwap = Standard_True;
graphicDriver_->InitEglContext(eglGetCurrentDisplay(), eglGetCurrentContext(), eglCore_->getConfig());
}
}
void NativeRender::initViewer(){
// 创建V3d_Viewer
if (!graphicDriver_.IsNull()) {
viewer_ = new V3d_Viewer(graphicDriver_);
viewer_->SetDefaultBackgroundColor (Quantity_NOC_BLACK);
viewer_->SetDefaultLights();
viewer_->SetLightOn();
}
float NativeRender::displayPixelRatio(){
float densityPixels;
NativeDisplayManager_ErrorCode errCode = OH_NativeDisplayManager_GetDefaultDisplayVirtualPixelRatio(&densityPixels);
if (errCode == NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "DMSTest", "rotation=%{public}d", densityPixels);
return densityPixels;
} else {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "DMSTest",
"GetDefaultDisplayRotation errCode=%{public}d", errCode);
}
}
void NativeRender::initContext(){
context_ = new AIS_InteractiveContext(viewer_);
context_->SetDisplayMode(AIS_Shaded, Standard_False); // 默认使用着色模式
context_->SetPixelTolerance (int(displayPixelRatio() * 6.0)); // increase tolerance and adjust to hi-dpi screens
//context_->SetPixelTolerance (int(NativeOpenCAX::DisplayInfo * 6.0)); // increase tolerance and adjust to hi-dpi screens
}
void NativeRender::initView() {
Handle(Aspect_NeutralWindow) m_Window = new Aspect_NeutralWindow();
@ -94,7 +81,7 @@ void NativeRender::initView() {
// 设置渲染参数
view_->SetImmediateUpdate (false);
//view_->ChangeRenderingParams().ToShowStats = true;
view_->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * displayPixelRatio() + 0.5);
//view_->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * displayPixelRatio() + 0.5);
view_->ChangeRenderingParams().Method = Graphic3d_RM_RASTERIZATION;
view_->ChangeRenderingParams().IsShadowEnabled = Standard_False;
view_->ChangeRenderingParams().IsReflectionEnabled = Standard_False;
@ -144,7 +131,6 @@ bool NativeRender::loadModel(const std::string& filePath) {
IFSelect_ReturnStatus status = reader.ReadFile(filePath.c_str());
if (status != IFSelect_RetDone) {
printf("Error: Failed to read STEP file: %s\n", filePath.c_str());
loadDefaultModel();
return false;
}
@ -153,7 +139,6 @@ bool NativeRender::loadModel(const std::string& filePath) {
int numShapes = reader.NbShapes();
if (numShapes <= 0) {
printf("Error: No shapes found in STEP file\n");
loadDefaultModel();
return false;
}
@ -196,52 +181,6 @@ bool NativeRender::loadModel(const std::string& filePath) {
return true;
}
void NativeRender::loadDefaultModel() {
// 创建一个默认的3D立方体
TopoDS_Shape box = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape();
Handle(AIS_Shape) aisBox = new AIS_Shape(box);
// 设置材质和颜色
Handle(Prs3d_Drawer) drawer = aisBox->Attributes();
Handle(Prs3d_ShadingAspect) shadingAspect = new Prs3d_ShadingAspect();
shadingAspect->SetColor(Quantity_NOC_RED);
shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC);
drawer->SetShadingAspect(shadingAspect);
context_->Display(aisBox, Standard_True);
shapes_.push_back(aisBox);
// 创建一个球体
TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(gp_Pnt(20.0, 0.0, 0.0), 5.0).Shape();
Handle(AIS_Shape) aisSphere = new AIS_Shape(sphere);
shadingAspect = new Prs3d_ShadingAspect();
shadingAspect->SetColor(Quantity_NOC_BLUE1);
shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC);
aisSphere->Attributes()->SetShadingAspect(shadingAspect);
context_->Display(aisSphere, Standard_True);
shapes_.push_back(aisSphere);
// 创建一个圆柱体
TopoDS_Shape cylinder = BRepPrimAPI_MakeCylinder(3.0, 15.0).Shape();
Handle(AIS_Shape) aisCylinder = new AIS_Shape(cylinder);
shadingAspect = new Prs3d_ShadingAspect();
shadingAspect->SetColor(Quantity_NOC_GREEN);
shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC);
aisCylinder->Attributes()->SetShadingAspect(shadingAspect);
gp_Trsf transform;
transform.SetTranslation(gp_Vec(-15.0, -15.0, 0.0));
aisCylinder->SetLocalTransformation(transform);
context_->Display(aisCylinder, Standard_True);
shapes_.push_back(aisCylinder);
// 调整相机
view_->FitAll(0.05, Standard_True);
view_->ZFitAll();
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "LoadDefaultModel","Loaded default model (cube, sphere, cylinder)");
}
//setTranslation
void NativeRender::setTranslation(float x, float y) {
translationX_ = x;

View File

@ -23,8 +23,6 @@
#include "common.h"
#include <EGL/egl.h>
#include "EGLCore.h"
#include <window_manager/oh_display_info.h>
#include <window_manager/oh_display_manager.h>
class Aspect_Window;
class gp_Quaternion;
@ -39,7 +37,6 @@ public:
bool init(int width, int height,EGLCore* eglCore);
bool loadModel(const std::string& filePath);
void loadDefaultModel();
void render();
void resize(int width, int height);
void setRotation(float xAngle, float yAngle);
@ -47,8 +44,9 @@ public:
void setClearColor(float r, float g, float b, float a);
void setZoomLevel(float zoom);
void setTranslation(float x, float y);
float displayPixelRatio();
private:
void initDriver();
void initViewer();
void initContext();
void initView();
@ -62,9 +60,11 @@ private:
Handle(AIS_InteractiveContext) context_;
Handle(Prs3d_TextAspect) text_;
std::vector<Handle(AIS_Shape)> shapes_;
//旋转X轴
float rotationX_;
//旋转Y轴
float rotationY_;
//旋转Z轴
float rotationZ_;
float zoomLevel_;

View File

@ -51,7 +51,6 @@ void NativeRenderThread::stop() {
}
void NativeRenderThread::renderLoop() {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "renderLoop","Thread ID: %{public}d",std::this_thread::get_id());
// 初始化EGL
if (!eglCore_->init(nativeWindow_)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","Failed to initialize EGL");

View File

@ -3,16 +3,15 @@ import { BtnEvent } from "../LayoutData/TitleInterface";
//单一功能按钮
@ComponentV2
export struct EventButton {
@Param strIcon:string='';
@Param strName:string='';
@Event btn:BtnEvent;
build() {
Column({ space: 2 }) {
// 请将$r('app.media.loading')替换为实际资源文件
Image($r('app.media.' + this.strIcon))
Image($r('app.media.' + this.btn.eIcon))
.width(45)
.height(35)
.objectFit(ImageFit.Contain)
Text(this.strName)
Text(this.btn.eName)
.fontSize(10)
.width(45)
.height(10)
@ -28,7 +27,7 @@ export struct EventButton {
//功能目录菜单,主要用于针对单一按钮多个功能形式
@ComponentV2
export struct EventBtnMenu {
@Param btnMenus: Array<BtnEvent>=[];
@Event btnMenus: Array<BtnEvent>=[];
@Builder
EventMenu(_btnMenus:Array<BtnEvent>){
Menu() {
@ -41,7 +40,7 @@ export struct EventBtnMenu {
}
}
build() {
EventButton({strIcon:this.btnMenus[0].eIcon,strName:this.btnMenus[0].eName}).bindMenu(this.EventMenu(this.btnMenus))
EventButton({btn:this.btnMenus[0]}).bindMenu(this.EventMenu(this.btnMenus))
}
}

View File

@ -4,8 +4,8 @@ import { BaseMenu } from "../LayoutData/TitleInterface";
//主要用于功能组操作菜单.文件下拉菜单等.
@ComponentV2
export struct GroupTextEventMenu {
@Param grpName:string =''
@Param grpMenus: Array<BaseMenu>=[];
@Event grpName:string =''
@Event grpMenus: Array<BaseMenu>=[];
@Builder
GroupMenu(menus: Array<BaseMenu>) {
ForEach(menus, (item: BaseMenu, index: number) => {
@ -18,11 +18,11 @@ export struct GroupTextEventMenu {
build(){
Row(){
//功能组名文本
Blank().width('10%')
Blank().width('auto')
Text(this.grpName)
.fontSize(8)
.fontColor(Color.Gray)
Blank().width('11%')
Blank().width('auto')
Image($r('app.media.base_seetings'))
.height(15)
.width(15)

View File

@ -1,6 +1,6 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { edgeColors } from '@kit.ArkUI';
import {TitleTab} from './TitleTab/TitleTab'
import {TitleTab} from './TitleTabLayout/TitleTab'
import {LeftSideTab} from './leftSideTab'
import {ModelViewTab} from './modelViewTab'
const DOMAIN = 0x0000;

View File

@ -29,6 +29,7 @@ export interface GroupEvent{
//功能组菜单
grpMenu:Array<BaseMenu>
}
export interface CAXModel{
//模块名
cmName:string
@ -36,22 +37,22 @@ export interface CAXModel{
cmPage:string
//模块提示
cmTips:string
//菜单列表
cmBtnEvents:Array<BtnEvent>
//模块布局数据
//第一个Array为TabContent的行数
//第二个Array为单行的按钮列表,该参数分为三种形态
//BtnEvent单按钮
//Array<GroupEvent>按钮组
//Array<BtnEvent>菜单按钮
cmEvents:Array<Array<BtnEvent|Array<GroupEvent>|Array<BtnEvent>>>
cmEvents:Array<Array<BtnEvent|Array<GroupEvent>|Array<BtnEvent>>>|Array<BtnEvent>
}
//Title配置
export interface TitleConfig{
//Title配置ID名(唯一)
mId:string;
//基础模块
mFileModel:CAXModel
//功能模块
mModel:Array<CAXModel>
mModels:Map<number,Array<CAXModel>>
}
//菜单配置
export interface BaseMenu{

View File

@ -5,7 +5,7 @@ import {
CAXModel,
GroupEvent,
Menu,
BtnEvent
BtnEvent,
}from './TitleInterface'
export let GroupMenu:Array<BaseMenu>=[
@ -21,11 +21,20 @@ export let RowMenu:Array<BaseMenu>=[
{str:'删除功能组',icon:'',tips:"",event:''},
{str:'移动功能组',icon:'',tips:"",event:''}
]
export let MatrixModel:CAXModel= {
cmName:"应用模块",cmPage:"",cmTips:"",cmEvents:[
[[{grpName:'模块矩阵',grpBtn:[
{eModel:[Model.BASE],eName:"建模",eNamed:"",eIcon:"base_new_file",eTips:"",eEvent:"Switch_Model_CAD"},
{eModel:[Model.BASE],eName:"加工",eNamed:"",eIcon:"base_open_file",eTips:"",eEvent:"Switch_Model_CAM"},
{eModel:[Model.BASE],eName:"仿真",eNamed:"",eIcon:"base_save_file",eTips:"",eEvent:"Switch_Model_CAE"},
],grpMenu:RowMenu}] as Array<GroupEvent>
]]
}
export let TitleData:TitleConfig= {
mId:"0",
mModel:[
//模块一
{cmName:"文件",cmPage:"",cmTips:"",cmBtnEvents:[
mFileModel:
{cmName:"文件",cmPage:"",cmTips:"",cmEvents:[
{eModel:[Model.BASE],eName:"新建",eNamed:"",eIcon:"base_new_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"打开",eNamed:"",eIcon:"base_open_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"保存",eNamed:"",eIcon:"base_save_file",eTips:"",eEvent:""},
@ -35,11 +44,10 @@ export let TitleData:TitleConfig= {
{eModel:[Model.BASE],eName:"选项",eNamed:"",eIcon:"base_preferences",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"帮助",eNamed:"",eIcon:"base_help",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"退出",eNamed:"",eIcon:"base_exit",eTips:"",eEvent:""},
],cmEvents:[]},
//模块二
{cmName:"主页",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:
//第一行
[
]},
mModels:new Map<number,Array<CAXModel>>([
[0,[
{cmName:'主页',cmPage:'',cmTips:'',cmEvents: [
//数组表示非单个BtnEvent
[
//数组成员区别是GroupEvent还是BtnEvent
@ -58,20 +66,64 @@ export let TitleData:TitleConfig= {
{eModel:[Model.BASE],eName:"帮助",eNamed:"",eIcon:"base_help_file",eTips:"",eEvent:""},
],grpMenu:RowMenu}] as Array<GroupEvent>
]
]},
{cmName:"建模",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"曲线",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"曲面",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"装配",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"多边建模",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"分析",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"选择",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"显示",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"工具",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"应用模块",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"关于",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]},
{cmName:"调试",cmPage:"",cmTips:"",cmBtnEvents:[],cmEvents:[]}
]},MatrixModel]],
[1,[
{cmName:'建模',cmPage:'',cmTips:'',cmEvents: [
//数组表示非单个BtnEvent
[
//数组成员区别是GroupEvent还是BtnEvent
[{grpName:'基础模型',grpBtn:[
{eModel:[Model.BASE],eName:"块",eNamed:"",eIcon:"base_new_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"圆柱",eNamed:"",eIcon:"base_open_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"圆锥",eNamed:"",eIcon:"base_close_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"球",eNamed:"",eIcon:"base_import_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"管道",eNamed:"",eIcon:"base_export_file",eTips:"",eEvent:""}
],grpMenu:RowMenu}] as Array<GroupEvent>
]
]},MatrixModel]],
[2,[
{cmName:'加工',cmPage:'',cmTips:'',cmEvents: [
//数组表示非单个BtnEvent
[
//数组成员区别是GroupEvent还是BtnEvent
[{grpName:'文件功能组',grpBtn:[
{eModel:[Model.BASE],eName:"新建",eNamed:"",eIcon:"base_new_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"打开",eNamed:"",eIcon:"base_open_file",eTips:"",eEvent:""},
[
{eModel:[Model.BASE],eName:"保存",eNamed:"",eIcon:"base_save_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"另存为",eNamed:"",eIcon:"base_saveas_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"保存全部",eNamed:"",eIcon:"base_saveall_file",eTips:"",eEvent:""},
] as Array<BtnEvent>,
{eModel:[Model.BASE],eName:"关闭",eNamed:"",eIcon:"base_close_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"导入",eNamed:"",eIcon:"base_import_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"导出",eNamed:"",eIcon:"base_export_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"选项",eNamed:"",eIcon:"base_open_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"帮助",eNamed:"",eIcon:"base_help_file",eTips:"",eEvent:""},
],grpMenu:RowMenu}] as Array<GroupEvent>
]
]},MatrixModel]],
[3,[
{cmName:'仿真',cmPage:'',cmTips:'',cmEvents: [
//数组表示非单个BtnEvent
[
//数组成员区别是GroupEvent还是BtnEvent
[{grpName:'文件功能组',grpBtn:[
{eModel:[Model.BASE],eName:"新建",eNamed:"",eIcon:"base_new_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"打开",eNamed:"",eIcon:"base_open_file",eTips:"",eEvent:""},
[
{eModel:[Model.BASE],eName:"保存",eNamed:"",eIcon:"base_save_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"另存为",eNamed:"",eIcon:"base_saveas_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"保存全部",eNamed:"",eIcon:"base_saveall_file",eTips:"",eEvent:""},
] as Array<BtnEvent>,
{eModel:[Model.BASE],eName:"关闭",eNamed:"",eIcon:"base_close_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"导入",eNamed:"",eIcon:"base_import_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"导出",eNamed:"",eIcon:"base_export_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"选项",eNamed:"",eIcon:"base_open_file",eTips:"",eEvent:""},
{eModel:[Model.BASE],eName:"帮助",eNamed:"",eIcon:"base_help_file",eTips:"",eEvent:""},
],grpMenu:RowMenu}] as Array<GroupEvent>
]
]},MatrixModel]]
])
}
export { TitleConfig, CAXModel }

View File

@ -5,16 +5,18 @@ import { SceneResourceType } from '@kit.ArkGraphics3D';
//导入布局模块
import {TitleData,TitleConfig,CAXModel} from '../LayoutData/TitleLayoutData'
import { BtnEvent } from '../LayoutData/TitleInterface'
import { BtnEvent, GroupEvent } from '../LayoutData/TitleInterface'
import {TitleTabContent} from './TitleTabContent'
@Component
@ComponentV2
export struct TitleTab {
//顶部导航组件
private titleBarTabs: TabsController = new TabsController();
//当前的顶部导航选择页
@State titleBarFocusIndex: number = 1;
@State titleBarDefaultFocusIndex: number = 1;
@Local titleBarFocusIndex: number = 0;
@Local titleBarDefaultFocusIndex: number = 0;
@Local currentModel:Array<CAXModel>|undefined= TitleData.mModels.get(0)
@Builder
FileMenu(menus: Array<BtnEvent>) {
Menu() {
@ -33,10 +35,15 @@ export struct TitleTab {
build() {
Flex({ direction: FlexDirection.Column }){
Scroll() {
Row() {
ForEach(TitleData.mModel, (item: CAXModel, index: number) => {
Row({ space: 1 }) {
if(index>0){
Row({space:0}) {
Button(TitleData.mFileModel.cmName)
.height(25)
.width(60)
.padding(5)
.bindMenu(this.FileMenu(TitleData.mFileModel.cmEvents as Array<BtnEvent>))
.type(ButtonType.Normal)
.backgroundColor(Color.Brown)
ForEach(this.currentModel, (item: CAXModel, index: number) => {
Button(item.cmName)
.fontWeight(index === this.titleBarFocusIndex ? FontWeight.Bold : FontWeight.Normal)
.height(25)
@ -44,25 +51,10 @@ export struct TitleTab {
.padding(5)
.type(ButtonType.Normal)
.backgroundColor(Color.Brown)
}else{
Button(item.cmName)
.fontWeight(index === this.titleBarFocusIndex ? FontWeight.Bold : FontWeight.Normal)
.height(25)
.width(60)
.padding(5)
.bindMenu(this.FileMenu(item.cmBtnEvents))
.type(ButtonType.Normal)
.backgroundColor(Color.Brown)
}
}.onClick(() => {
if(index!=0){
.onClick(() => {
this.titleBarTabs.changeIndex(index);
this.titleBarFocusIndex = index;
}else{
this.titleBarTabs.changeIndex(this.titleBarDefaultFocusIndex);
this.titleBarFocusIndex = this.titleBarDefaultFocusIndex;
}
this.currentModel=TitleData.mModels.get(index);
})
})
}
@ -73,11 +65,9 @@ export struct TitleTab {
.margin({ top: 2,left:2,bottom:2,right:2})
.width('100%')
Tabs({barPosition: BarPosition.Start, index: this.titleBarDefaultFocusIndex,controller: this.titleBarTabs}){
ForEach(TitleData.mModel,(item:CAXModel, index: number)=>{
ForEach(this.currentModel,(item:CAXModel, index: number)=>{
TabContent() {
if(item.cmBtnEvents.length==0){
TitleTabContent({tabLayout:item.cmEvents})
}
TitleTabContent({tabLayout:item.cmEvents as Array<Array<BtnEvent|Array<GroupEvent>|Array<BtnEvent>>>})
}.align(Alignment.Start)
.padding(1)
.margin({ top: 0,left:0,bottom:2,right:0})

View File

@ -18,7 +18,7 @@ export struct TitleTabContent {
//首先判断是否为数组.如果不为数组者为BtnEvent
if(!Array.isArray(row_item)){
//单按钮
EventButton({strIcon:row_item.eIcon,strName:row_item.eName})
EventButton({btn:row_item})
}else if(row_item instanceof Array<GroupEvent>){
//功能组,迭代多个功能组
ForEach(row_item, (group_item: GroupEvent, index: number) =>{
@ -29,7 +29,7 @@ export struct TitleTabContent {
if(Array.isArray(btn_item)){
EventBtnMenu({btnMenus:btn_item})
}else{
EventButton({strIcon:btn_item.eIcon,strName:btn_item.eName})
EventButton({btn:btn_item})
}
})
}.margin({ top: 1,left:1,bottom:1,right:1})