1-重新实现资源字体释放到沙箱,首次启动不再崩溃

2-对于实时主窗口大小进行解耦
3-新增组件样式解耦
This commit is contained in:
JackLee 2026-04-07 19:45:12 +08:00
parent 4a72555468
commit ad7b56395d
79 changed files with 260 additions and 239 deletions

View File

@ -1,7 +1,20 @@
{
"app": {
"signingConfigs": [],
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"certpath": "C:\\Users\\JackLee\\.ohos\\config\\default_OpenCAX_IBQbNZG6W5V0zTmQxRPojupy-F1gTlaQ6msiMPu4JRM=.cer",
"keyAlias": "debugKey",
"keyPassword": "0000001BD635371F28E25E69BF1D7E55AB1BFBCCA66E5359C1DD49F7D565DDB1312AE20C7481F7318E1EAB",
"profile": "C:\\Users\\JackLee\\.ohos\\config\\default_OpenCAX_IBQbNZG6W5V0zTmQxRPojupy-F1gTlaQ6msiMPu4JRM=.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "C:\\Users\\JackLee\\.ohos\\config\\default_OpenCAX_IBQbNZG6W5V0zTmQxRPojupy-F1gTlaQ6msiMPu4JRM=.p12",
"storePassword": "0000001B3048C3F197421E5E1DEDC267DB510037100BA2AF0FE4444CBA15D3CEC9D10CCF6B88E21FAD8104"
}
}
],
"products": [
{
"name": "default",

View File

@ -6,11 +6,11 @@
"arguments": "",
"cppFlags": "",
"abiFilters": [
"x86_64"
"x86_64",
"arm64-v8a"
]
}
},
"buildOptionSet": [
{
"name": "release",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -23,10 +23,17 @@ set(OCCT_CORE_LIBS
TKDESTEP TKShHealing TKHLR TKVCAF TKBO TKPrim TKBool TKDE TKXSBase
)
if(OHOS_ARCH STREQUAL "x86_64")
set(OCCT_3RD_LIBS
libfreetype.so.6 libharfbuzz.so libbz2.so libbrotlienc.so.1
libbrotlidec.so.1 libbrotlicommon.so.1 libpng16.so.16
)
else()
set(OCCT_3RD_LIBS
libfreetype.so.6 libbz2.so libbrotlienc.so.1
libbrotlidec.so.1 libbrotlicommon.so.1 libpng16.so.16
)
endif()
foreach(LIB_NAME ${OCCT_CORE_LIBS})
list(APPEND OCCT_IMPORTED_LIBS ${OCCT_LIB_DIR}/lib${LIB_NAME}.so.${OCCT_VERSION})

View File

@ -1,9 +1,9 @@
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window, display, AppStorageV2 } from '@kit.ArkUI';
import { MainScreenDisplayInfo, MainWindowInfo, MainWindowStageInfo } from '../pages/AppStorageV2Class'
import { IBestInit } from "@ibestservices/ibest-ui-v2"
import {ExtractFonts,HilogSadboxFontDirFile} from "../pages/ExtractFonts/ExtractFonts"
import {MainWindowStageInfo,InitGlobalDisplayWindowInfo,mwInfo}from '../pages/DispWinInfo/DispWinInfo'
const DOMAIN = 0x0000;
export default class EntryAbility extends UIAbility {
@ -22,29 +22,14 @@ export default class EntryAbility extends UIAbility {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(DOMAIN, 'Tag', '%{public}s', 'Ability onWindowStageCreate');
//Get DefaultDispplay width&&height&&id
const screenDisplayId: number = display.getDefaultDisplaySync().id;
const screenWidth: number = display.getDefaultDisplaySync().width;
const screenHeight: number = display.getDefaultDisplaySync().height;
//Set Main Window Size
const mainWindowWidth: number = screenWidth - 100;
const mainWindowHeight: number = screenHeight - 200;
console.error(`main window Width: mainWindowWidth, Height: mainWindowHeight`);
//Init&&Save AppStorageV2
const mDispInfo =
AppStorageV2.connect<MainScreenDisplayInfo>(MainScreenDisplayInfo, () => new MainScreenDisplayInfo())!;
const mWinInfo = AppStorageV2.connect<MainWindowInfo>(MainWindowInfo, () => new MainWindowInfo())!;
const mWinStage =
AppStorageV2.connect<MainWindowStageInfo>(MainWindowStageInfo, () => new MainWindowStageInfo())!;
mDispInfo.mSDispId = screenDisplayId;
mDispInfo.mSDispWidth = screenWidth;
mDispInfo.mSDispHeight = screenHeight;
mWinInfo.mWinWidth = mainWindowWidth;
mWinInfo.mWinHeight = mainWindowHeight;
mWinStage.mWinStage = windowStage;
async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
//InitFont->Copy Res/resfile/font to sandbox
if(!await ExtractFonts(this.context)){
return;
}else{
HilogSadboxFontDirFile(this.context);
await InitGlobalDisplayWindowInfo(windowStage);
}
//Get Main Window
windowStage.getMainWindow((err, data) => {
@ -53,23 +38,23 @@ export default class EntryAbility extends UIAbility {
return;
}
this.mainWindow = data;
mWinInfo.mWinId = this.mainWindow.getWindowProperties().id;
mwInfo.id = this.mainWindow.getWindowProperties().id;
//moveWindowTo
this.mainWindow.moveWindowTo(50, 50)
//resize mainWindow Size
this.mainWindow.resize(mainWindowWidth, mainWindowHeight, (err) => {
this.mainWindow.resize(mwInfo.width, mwInfo.height, (err) => {
if (err.code) {
console.error(`Failed to resize the window. Code: ${err.code}, message: ${err.message}`);
return;
}
console.info(`Succeeded in resizing the window to ${mainWindowWidth}x${mainWindowHeight}.`);
console.info(`Succeeded in resizing the window to ${mwInfo.width}x${mwInfo.height}.`);
});
// windowSizeChangeListener to Change mainWindowWidth&&mainWindowHeight in AppStorage
this.mainWindow.on('windowSizeChange', (ListenerData) => {
// if Size Change save to AppStorage
mWinInfo.mWinWidth = ListenerData.width;
mWinInfo.mWinHeight = ListenerData.height;
mwInfo.width = ListenerData.width;
mwInfo.height = ListenerData.height;
console.info('Succeeded in enabling the listener for window size changes. Data:' + ListenerData.width,
ListenerData.height);
});

View File

@ -1,45 +0,0 @@
import { AppStorageV2, window} from '@kit.ArkUI';
//该文档主要储存屏幕信息,主窗口信息,窗口管理信息
//底部有全局信息变量,已导出,其他page只需要import该文件即可调用let变量
@ObservedV2
export class MainScreenDisplayInfo {
@Trace public mSDispId: number;
@Trace public mSDispWidth: number;
@Trace public mSDispHeight: number;
constructor(_id?: number, _width?: number,_height?: number) {
this.mSDispId = _id ?? 0;
this.mSDispWidth = _width ?? 0;
this.mSDispHeight = _height ?? 0;
}
}
@ObservedV2
export class MainWindowInfo {
@Trace public mWinId: number;
@Trace public mWinWidth: number;
@Trace public mWinHeight: number;
constructor(_id?:number,_width?: number, _height?: number) {
this.mWinWidth = _width ?? 0;
this.mWinHeight = _height ?? 0;
this.mWinId=_id?? 0;
}
}
@ObservedV2
export class MainWindowStageInfo {
@Trace public mWinStage: window.WindowStage| undefined;
constructor(_ws?: window.WindowStage) {
this.mWinStage = _ws ?? undefined;
}
}
//全局保存主窗口信息,屏幕信息.窗口管理器信息
export let mwInfo: MainWindowInfo = AppStorageV2.connect<MainWindowInfo>(MainWindowInfo, () => new MainWindowInfo())!;
export let msdInfo: MainScreenDisplayInfo = AppStorageV2.connect<MainScreenDisplayInfo>(MainScreenDisplayInfo, () => new MainScreenDisplayInfo())!;
export let mwsInfo: MainWindowStageInfo = AppStorageV2.connect<MainWindowStageInfo>(MainWindowStageInfo, () => new MainWindowStageInfo())!;

View File

@ -3,13 +3,13 @@ import { ExecuteCommand } from '../EventSubWin/ExCom';
import { TitleButton } from "../LayoutInterface/Interface/ButtonInterface";
import { TitleModel } from "../LayoutInterface/Interface/ModelInterface";
import { TitleTabData } from '../LayoutInterface/Layout/TitleTabData';
import { mwInfo } from '../AppStorageV2Class';
import { mwInfo } from '../DispWinInfo/DispWinInfo'
//按钮统一尺寸,该按钮为正方形,所以以主窗口宽为基准,长=高->正方形
let ebWidth=mwInfo.mWinWidth*0.02;
let ebHeigth=mwInfo.mWinWidth*0.02;
let ebWidth=mwInfo.width*0.02;
let ebHeigth=mwInfo.width*0.02;
//占位符的高度
let edHeigth=mwInfo.mWinWidth*0.005
let edHeigth=mwInfo.width*0.005
//单一功能按钮
@ -26,6 +26,7 @@ export struct EventBtn {
//模块切换模块按钮数据
@Consumer('curtModel') curtModel: Array<TitleModel> | undefined = TitleTabData.mModels.get(0)
@Builder
build() {
Column({ space: 2 }) {
//如果该类型是false表示为配普通事件按钮
@ -180,15 +181,15 @@ export struct SubColumnMenu {
Button(){
Row(){
Image($r('app.media.'+(this.icon!=undefined ? this.icon:(this.menus[this.curtIndex]as TitleButton).eIcon)))
.height(mwInfo.mWinWidth*0.01)
.height(mwInfo.width*0.01)
if(this.name!=undefined){
Text(this.name).fontSize(16)
}
}
}.height(mwInfo.mWinWidth*0.01)
}.height(mwInfo.width*0.01)
.backgroundColor(Color.Transparent)
.bindMenu(this.BaseMenu)
.type(ButtonType.Normal)
}.width(this.name!=undefined ?mwInfo.mWinWidth*0.02:mwInfo.mWinWidth*0.01)
}.width(this.name!=undefined ?mwInfo.width*0.02:mwInfo.width*0.01)
}
}

View File

@ -1,11 +1,11 @@
import { mwInfo } from "../AppStorageV2Class";
import { mwInfo } from '../DispWinInfo/DispWinInfo'
import { TitleButton } from "../LayoutInterface/Interface/ButtonInterface";
//按钮统一尺寸,该按钮为正方形,所以以主窗口宽为基准,长=高->正方形
let ebWidth=mwInfo.mWinWidth*0.075;
let ebHeigth=mwInfo.mWinHeight*0.03;
let ebWidth=mwInfo.width*0.075;
let ebHeigth=mwInfo.height*0.03;
//占位符的高度
let edHeigth=mwInfo.mWinWidth*0.005
let edHeigth=mwInfo.width*0.005
@ComponentV2
export struct TextComboBox {
@ -34,10 +34,10 @@ export struct TextComboBox {
.width('50%')
.fontSize(16)
.backgroundColor('#ffe6e6e3')
.height(mwInfo.mWinHeight*0.02)
.height(mwInfo.height*0.02)
.margin({ top:0, left: 5, bottom: 0, right: 0 })
}.width(ebWidth)
.height(mwInfo.mWinWidth*0.01)
.height(mwInfo.width*0.01)
}
}
@ComponentV2
@ -61,6 +61,6 @@ export struct TextInputComboBox {
TextInput({placeholder:this.selectIndex.toString()})
.bindMenu(this.EventMenu)
.type(InputType.Number)
}.height(mwInfo.mWinWidth*0.01)
}.height(mwInfo.width*0.01)
}
}

View File

@ -1,11 +1,11 @@
import { mwInfo } from "../AppStorageV2Class";
import { mwInfo } from '../DispWinInfo/DispWinInfo'
import { ExecuteCommand } from "../EventSubWin/ExCom";
import { TitleButton } from "../LayoutInterface/Interface/ButtonInterface";
import {SwitchView} from "../LayoutInterface/Layout/SwitchView"
//按钮统一尺寸,该按钮为正方形,所以以主窗口宽为基准,长=高->正方形
let ebWidth=mwInfo.mWinWidth*0.02;
let ebHeigth=mwInfo.mWinWidth*0.02;
let ebWidth=mwInfo.width*0.02;
let ebHeigth=mwInfo.width*0.02;
//视图切换弹窗
@CustomDialog
export struct ViewDialog {

View File

@ -1,13 +1,13 @@
import { TitleGroup } from "../LayoutInterface/Interface/GroupInterface";
import { TitleButton } from "../LayoutInterface/Interface/ButtonInterface";
import { ExecuteCommand } from "../EventSubWin/ExCom";
import { mwInfo } from "../AppStorageV2Class";
import { mwInfo } from '../DispWinInfo/DispWinInfo'
import { BaseMenuData } from "../LayoutInterface/Interface/MenuInterface";
//按钮统一尺寸,该按钮为正方形,所以以主窗口宽为基准,长=高->正方形
let ebWidth=mwInfo.mWinWidth*0.02;
let ebHeigth=mwInfo.mWinWidth*0.02;
let ebWidth=mwInfo.width*0.02;
let ebHeigth=mwInfo.width*0.02;
@Builder
export function BaseMenu(indexMenu:BaseMenuData) {
@ -66,8 +66,8 @@ export struct GroupTextEventMenu {
.fontColor(Color.Gray)
Blank().width('auto')
Button()
.height(mwInfo.mWinWidth*0.005)
.width(mwInfo.mWinWidth*0.005)
.height(mwInfo.width*0.005)
.width(mwInfo.width*0.005)
.padding(1)
.backgroundImage($r('app.media.base_seetings'))
.backgroundImagePosition({ x: '5%', y: '5%' })

View File

@ -0,0 +1,57 @@
import { AppStorageV2, display,window} from '@kit.ArkUI';
//该文档主要储存屏幕信息,主窗口信息,窗口管理信息
//底部有全局信息变量,已导出,其他page只需要import该文件即可调用let变量
@ObservedV2
export class MainDisplayInfo {
@Trace public id: number;
@Trace public width: number;
@Trace public height: number;
constructor(_id?: number, _width?: number,_height?: number) {
this.id = _id ?? 0;
this.width = _width ?? 0;
this.height = _height ?? 0;
}
}
@ObservedV2
export class MainWindowInfo {
@Trace public id: number;
@Trace public width: number;
@Trace public height: number;
constructor(_id?:number,_width?: number, _height?: number) {
this.id = _width ?? 0;
this.width = _height ?? 0;
this.height=_id?? 0;
}
}
@ObservedV2
export class MainWindowStageInfo {
@Trace public winStage: window.WindowStage| undefined;
constructor(_ws?: window.WindowStage) {
this.winStage = _ws ?? undefined;
}
}
export async function InitGlobalDisplayWindowInfo(windowStage: window.WindowStage){
const mainDisplayInfo = AppStorageV2.connect<MainDisplayInfo>(MainDisplayInfo, () => new MainDisplayInfo())!;
const mainWindowInfo = AppStorageV2.connect<MainWindowInfo>(MainWindowInfo, () => new MainWindowInfo())!;
const mainWindowStage = AppStorageV2.connect<MainWindowStageInfo>(MainWindowStageInfo, () => new MainWindowStageInfo())!;
mainDisplayInfo.id = display.getDefaultDisplaySync().id;
mainDisplayInfo.width = display.getDefaultDisplaySync().width;
mainDisplayInfo.height = display.getDefaultDisplaySync().height;
mainWindowInfo.width = mainDisplayInfo.width-100;
mainWindowInfo.height = mainDisplayInfo.height-200;
mainWindowStage.winStage = windowStage;
console.error(`Display Width:%{public}d, Height: %{public}d`,mainDisplayInfo.width,mainDisplayInfo.height);
console.error(`MainWindow Width:%{public}d, Height: %{public}d`,mainWindowInfo.width,mainWindowInfo.height);
}
//全局保存主窗口信息,屏幕信息.窗口管理器信息
export let mwInfo: MainWindowInfo = AppStorageV2.connect<MainWindowInfo>(MainWindowInfo, () => new MainWindowInfo())!;
export let mdInfo: MainDisplayInfo = AppStorageV2.connect<MainDisplayInfo>(MainDisplayInfo, () => new MainDisplayInfo())!;
export let mwsInfo: MainWindowStageInfo = AppStorageV2.connect<MainWindowStageInfo>(MainWindowStageInfo, () => new MainWindowStageInfo())!;

View File

@ -1,7 +1,7 @@
import { TitleButton } from '../LayoutInterface/Interface/ButtonInterface';
import { CloseSubWindow, CreateAndShowSubWindow, WinInfo} from './SWBase';
import NativeOpenCAX from 'libopencax.so';
import { mwInfo } from '../AppStorageV2Class';
import { mwInfo } from '../DispWinInfo/DispWinInfo'
import { AppStorageV2, NodeContent} from '@kit.ArkUI';
import { ModelViewTab } from '../ModelViewTab';
@ -88,13 +88,13 @@ export function ExecuteCommand(event:TitleButton){
//窗体打开
if(event?.eEvent=='Execute_CreateSubWindow'){
const winInfo:WinInfo=new WinInfo(event.eName,event.ePage,mwInfo.mWinWidth*0.3,mwInfo.mWinHeight*0.9);
const winInfo:WinInfo=new WinInfo(event.eName,event.ePage,mwInfo.width*0.3,mwInfo.height*0.9);
//CreateAndShowSubWindow(winInfo);
}else if(event?.eEvent=='Execute_ExitSubWindow'){
CloseSubWindow();
} else if(event?.eEvent=='Execute_CreateSubWindow_Options'){
const winInfo:WinInfo=new WinInfo(event.eName,event.ePage,mwInfo.mWinWidth*0.6,mwInfo.mWinHeight*0.9);
const winInfo:WinInfo=new WinInfo(event.eName,event.ePage,mwInfo.width*0.6,mwInfo.height*0.9);
CreateAndShowSubWindow(winInfo);
}else if(event?.eEvent=='Execute_ExitSubWindow_Options'){
CloseSubWindow();

View File

@ -1,7 +1,6 @@
import { BusinessError } from '@kit.BasicServicesKit';
import { window} from '@kit.ArkUI';
import { mwInfo, mwsInfo } from '../AppStorageV2Class';
import { mwInfo, mwsInfo } from '../DispWinInfo/DispWinInfo'
let subWindow: window.Window | undefined = undefined;
export class WinInfo{
@ -19,7 +18,7 @@ export class WinInfo{
export async function CreateAndShowSubWindow(winInfo:WinInfo) {
try {
if(mwsInfo.mWinStage==null){
if(mwsInfo.winStage==null){
console.error('Failed to create the subwindow. Cause: windowStage is null');
return;
}
@ -31,7 +30,7 @@ export async function CreateAndShowSubWindow(winInfo:WinInfo) {
outlineEnabled:true,
};
await mwsInfo.mWinStage.createSubWindowWithOptions('subWindow', options).then((data) => {
await mwsInfo.winStage.createSubWindowWithOptions('subWindow', options).then((data) => {
subWindow = data;
//子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
subWindow.moveWindowTo(25, 25)

View File

@ -1,5 +1,4 @@
import { mwInfo } from '../AppStorageV2Class';
import { Expandable } from '../CustomStyle/Expandable';
import { Expandable } from '../CustomController/Expandable';
@Entry
@ComponentV2

View File

@ -0,0 +1,93 @@
import fs from '@ohos.file.fs';
let Fonts: Array<string> = [
"HarmonyOS_Sans_Black.tff",
"HarmonyOS_Sans_Bold.tff",
"HarmonyOS_Sans_Light.tff",
"HarmonyOS_Sans_Medium.tff",
"HarmonyOS_Sans_Regular.tff",
"HarmonyOS_Sans_Semibold.tff",
"HarmonyOS_Sans_Thin.tff",
]
//列出资源管理器指定目录下的所有问题件
export function HilogSadboxFontDirFile(ctx: Context){
// 获取资源管理器
const rm = ctx?.filesDir+'/fonts/';
fs.listFile(rm).then((filenames: Array<string>) => {
console.info('沙箱文件信息'); // 打印成功日志
console.info('目录路径:'+rm); // 打印成功日志
console.log('指定目录文件数: ' + filenames.length) // 打印文件数量
// 遍历打印所有文件名到控制台
for (let i = 0; i < filenames.length; i++) {
console.log('文件名:', filenames[i]);
}
}).catch((err: BusinessError) => {
// 捕获并打印文件列表获取失败的错误信息
console.error('list file failed with error message: ' + err.message + ', error code: ' + err.code);
});
}
export async function CheckExistDir(dir:string):Promise<boolean>{
if (!dir || typeof dir !== 'string') {
console.error('Invalid directory path provided.');
return false;
}
try {
// 使用 fs.stat 获取路径的状态信息
const stat = await fs.stat(dir);
// 检查路径是否存在且是一个目录
if (stat && stat.isDirectory()) {
console.info(`Directory exists: ${dir}`);
return true;
} else {
console.info(`Path exists but is not a directory: ${dir}`);
return false;
}
} catch (error) {
// fs.stat 如果路径不存在会抛出错误
const businessError = error as BusinessError;
if (businessError.code === 101) { // 错误码 101 通常代表文件或目录不存在,请根据实际文档确认
console.info(`Directory does not exist: ${dir}`);
} else {
// 其他错误,如权限不足等
console.error(`Error checking directory existence: ${businessError.message}, code: ${businessError.code}`);
}
return false; // 发生错误,视为目录不存在或无法访问
}
}
//复制字体到沙盒指定目录
//SandBoxFontDir:"/data/storage/el2/base/haps/entry/files/fonts"
export async function ExtractFonts(ctx: Context):Promise<boolean>{
//err->true表示复制成功
//err->表示复制失败
try {
//初始化源Fonts目录和沙箱Fonts目录路径
let srcPath = ctx?.resourceDir+ '/fonts/';
let destPath = ctx?.filesDir + '/fonts/';
//检测目录是否存在
let srcDirState:boolean=await CheckExistDir(srcPath);
let destDirState:boolean=await CheckExistDir(destPath);
//源字体目录不存在则返回.->直接无法系统
if(!srcDirState){
return false;
}
//如果沙箱目录不存在则创建目录
if(!destDirState){
fs.mkdir(destPath);
console.info('Created sandbox directory successfully:', destPath);
}else{
return true;
}
fs.copyDir(srcPath, destPath);
console.info('Fonts copied to sandbox successfully.');
return true;
} catch (err) {
let msg = 'Unknown error';
if (err instanceof Error) {
msg = err.message;
} else if (typeof err === 'string') {
msg = err;
}
console.error(`Copy failed: ${msg}`);
return false;
}
}

View File

@ -4,111 +4,23 @@ import { TitleTab } from './TitleLayout/TitleTab'
import { LeftSideTab } from './LeftSideLayout/LeftSideTab'
import { ModelViewTab } from './ModelViewTab'
import { TitleColumnSub } from './TitleLayout/TitleColumnSub'
import { mwInfo } from './AppStorageV2Class'
import fs from '@ohos.file.fs';
import { mwInfo } from './DispWinInfo/DispWinInfo'
const DOMAIN = 0x0000;
let Fonts: Array<string> = [
"HarmonyOS_Sans_Black.tff",
"HarmonyOS_Sans_Bold.tff",
"HarmonyOS_Sans_Light.tff",
"HarmonyOS_Sans_Medium.tff",
"HarmonyOS_Sans_Regular.tff",
"HarmonyOS_Sans_Semibold.tff",
"HarmonyOS_Sans_Thin.tff",
]
@Entry
@ComponentV2
struct Index {
@Local startX:number=0;
@Local isDragging:boolean=false;
@Provider('panelWidth') panelWidth:number=mwInfo.mWinWidth * 0.15;
//列出资源管理器指定目录下的所有问题件
HilogToDirFile(){
const context = this.getUIContext().getHostContext();
// 获取资源管理器
const rm = context?.filesDir+'/fonts/';
fs.listFile(rm).then((filenames: Array<string>) => {
console.info('沙箱文件信息'); // 打印成功日志
console.info('目录路径:'+rm); // 打印成功日志
console.log('指定目录文件数: ' + filenames.length) // 打印文件数量
// 遍历打印所有文件名到控制台
for (let i = 0; i < filenames.length; i++) {
console.log('文件名:', filenames[i]);
}
}).catch((err: BusinessError) => {
// 捕获并打印文件列表获取失败的错误信息
console.error('list file failed with error message: ' + err.message + ', error code: ' + err.code);
});
}
//复制字体到沙盒指定目录
//SandBoxFontDir:"/data/storage/el2/base/haps/entry/files/fonts"
CopyFontToSandbox() {
try {
const context = this.getUIContext().getHostContext();
let srcPath = context?.resourceDir+ '/fonts/';
let destPath = context?.filesDir + '/fonts/';
if (!srcPath || !destPath) {
throw new Error('Resource or files directory is not available.');
}
console.info('srcPath', srcPath);
console.info('destPath', destPath);
// 1. 检查源目录是否存在
try {
fs.access(srcPath);
} catch (error) {
console.error('Source directory does not exist:', srcPath);
return; // 或者抛出错误
}
// 2. 创建目标目录
// 使用 mkdir 同步或异步版本,并处理已存在的异常
try {
fs.mkdir(destPath);
console.info('Created sandbox directory successfully:', destPath);
} catch (mkdirErr) {
// 如果目录已存在mkdir 会失败,这通常是无害的
console.info('Sandbox directory already exists:', destPath);
}
// 3. 复制目录
// 关键修改点:移除第三个参数 '1',该参数是无效的。
// 可以选择性地添加一个空的 flags 对象 {}
fs.copyDir(srcPath, destPath);
console.info('Fonts copied to sandbox successfully.');
} catch (err) {
let msg = 'Unknown error';
if (err instanceof Error) {
msg = err.message;
} else if (typeof err === 'string') {
msg = err;
}
console.error(`Copy failed: ${msg}`);
// 注意:模板字符串需要反引号 ``,您原代码中的单引号 '' 会直接输出变量名
throw new Error(`Failed to copy to sandbox: ${msg}`);
}
}
//Copy Font File to Sandbox
aboutToAppear() {
this.CopyFontToSandbox();
//输出沙盘下得文件名
this.HilogToDirFile();
}
@Provider('panelWidth') panelWidth:number=mwInfo.width * 0.15;
build() {
//OpenCAX主界面整体布局,采用多行布局
Column({ space: 0 }) {
//头部导航功能区
TitleTab()
.height(mwInfo.mWinHeight * 0.08)
.height(mwInfo.height * 0.08)
//分割线
Divider().vertical(false).strokeWidth(1).lineCap(LineCapStyle.Round).width('100%').backgroundColor(Color.Grey)
//工具栏
@ -116,7 +28,7 @@ struct Index {
TitleColumnSub();
}
.width('100%')
.height(mwInfo.mWinHeight * 0.02)
.height(mwInfo.height * 0.02)
.align(Alignment.Start)
//分割线
Divider().vertical(false).strokeWidth(1).lineCap(LineCapStyle.Round).width('100%').backgroundColor(Color.Grey)
@ -147,7 +59,7 @@ struct Index {
}.layoutWeight(1)
.align(Alignment.Center)
}.width('100%')
.height(mwInfo.mWinHeight * 0.39)
.height(mwInfo.height * 0.39)
//分割线
Divider().vertical(false).strokeWidth(1).lineCap(LineCapStyle.Round).width('100%').backgroundColor(Color.Grey)
///状态栏
@ -156,7 +68,7 @@ struct Index {
}.width('100%')
.align(Alignment.End)
.alignItems(HorizontalAlign.Start)
.height(mwInfo.mWinHeight * 0.01)
.height(mwInfo.height * 0.01)
}.backgroundColor('#f3f3f0')
.width('100%')
.height('100%')

View File

@ -1,13 +1,13 @@
import { TitleButton } from '../LayoutInterface/Interface/ButtonInterface';
import {LeftSideBars} from '../LayoutInterface/Layout/LeftSideBar'
import { mwInfo } from '../AppStorageV2Class';
import { mwInfo } from '../DispWinInfo/DispWinInfo'
import {LeftSideComponent} from './LeftSideComponent'
@ComponentV2
export struct LeftSideTab {
private leftSideBarTabs: TabsController = new TabsController();
@Local leftSideBarFocusIndex: number = 0;
@Local isExpanded:boolean=true;
@Consumer('panelWidth') panelWidth:number=mwInfo.mWinWidth * 0.1;
@Consumer('panelWidth') panelWidth:number=mwInfo.width * 0.1;
build() {
Row() {
@ -24,12 +24,12 @@ export struct LeftSideTab {
})
.backgroundImage(this.isExpanded ? $r('app.media.base_expand_on'):$r('app.media.base_expand_off'))
.type(ButtonType.Normal)
.width(mwInfo.mWinWidth*0.013)
.height(mwInfo.mWinWidth*0.013)
.width(mwInfo.width*0.013)
.height(mwInfo.height*0.013)
.onClick(()=>{
this.isExpanded = !this.isExpanded;
if(this.isExpanded){
this.panelWidth=mwInfo.mWinWidth * 0.1;
this.panelWidth=mwInfo.width * 0.1;
}else{
this.panelWidth=0;
}
@ -50,8 +50,8 @@ export struct LeftSideTab {
})
.backgroundImage($r('app.media.'+item.eIcon))
.fontWeight(index === this.leftSideBarFocusIndex ? FontWeight.Bold : FontWeight.Normal)
.width(mwInfo.mWinWidth*0.013)
.height(mwInfo.mWinWidth*0.013)
.width(mwInfo.width*0.013)
.height(mwInfo.width*0.013)
.type(ButtonType.Normal)
.onClick(() => {
this.leftSideBarTabs.changeIndex(index);
@ -64,8 +64,8 @@ export struct LeftSideTab {
.align(Alignment.Start)
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.Off)
.width(mwInfo.mWinWidth*0.013)
.height(mwInfo.mWinWidth*0.013)
.width(mwInfo.width*0.013)
.height(mwInfo.width*0.013)
.height('100%')
}.borderWidth(1)
.borderColor(Color.Grey)

View File

@ -1,12 +1,11 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { MainWindowInfo } from './AppStorageV2Class';
import { mwInfo } from './DispWinInfo/DispWinInfo'
import { AppStorageV2 } from '@kit.ArkUI';
import {InitXCompNode,XCompInfos,XCompInfo,CurrentXCompIndex} from './EventSubWin/ExCom'
@ComponentV2
export struct ModelViewTab {
@Local mwInfo: MainWindowInfo = AppStorageV2.connect<MainWindowInfo>(MainWindowInfo, () => new MainWindowInfo())!;
@Local xcInfos: XCompInfos = AppStorageV2.connect<XCompInfos>(XCompInfos, () => new XCompInfos)!;
//顶部导航组件
private barTabs: TabsController = new TabsController();
@ -23,18 +22,18 @@ export struct ModelViewTab {
ForEach(this.xcInfos.infos, (item: XCompInfo, index: number) => {
Row({ space: 0 }) {
Image($r('app.media.startIcon'))
.width(this.mwInfo.mWinWidth*0.012)
.height(this.mwInfo.mWinWidth*0.012)
.width(mwInfo.width*0.012)
.height(mwInfo.width*0.012)
.objectFit(ImageFit.Contain)
Button(item.name)
.fontWeight(index === this.barFocusIndex ? FontWeight.Bold : FontWeight.Normal)
.width('auto')
.height(this.mwInfo.mWinWidth*0.012)
.height(mwInfo.width*0.012)
.type(ButtonType.Normal)
Button('X')
.fontSize(12)
.width(this.mwInfo.mWinWidth*0.012)
.height(this.mwInfo.mWinWidth*0.012)
.width(mwInfo.width*0.012)
.height(mwInfo.width*0.012)
.type(ButtonType.Normal)
.align(Alignment.Center)
}.onClick(() => {

View File

@ -1,13 +1,13 @@
import { TextComboBox,TextInputComboBox } from "../CustomStyle/ComboBox";
import { TextComboBox,TextInputComboBox } from "../CustomController/ComboBox";
import { TitleButton } from "../LayoutInterface/Interface/ButtonInterface";
import { ViewDialog } from "../CustomStyle/Dialog"
import { ViewDialog } from "../CustomController/Dialog"
import { SwitchView } from "../LayoutInterface/Layout/SwitchView";
import {SelectionFilter} from "../LayoutInterface/Layout/SelectionFilter"
import {DisplayMode} from "../LayoutInterface/Layout/DisplayMode"
import { LayoutSwitch } from "../LayoutInterface/Layout/LayoutSwitch";
import { FileMenuData } from "../LayoutInterface/Layout/FileMenuData";
import { mwInfo } from "../AppStorageV2Class";
import { SubColumnMenu} from "../CustomStyle/Button";
import { mwInfo } from '../DispWinInfo/DispWinInfo'
import { SubColumnMenu} from "../CustomController/Button";
import { fileIo } from "@kit.CoreFileKit";
@ -22,8 +22,8 @@ export struct TitleColumnSub {
private ViewDialog(): CustomDialogController {
return new CustomDialogController({
builder: ViewDialog(), // 确保 ViewDialog 组件已正确定义
width: mwInfo.mWinWidth*0.06,
height: mwInfo.mWinWidth*0.052,
width: mwInfo.width*0.06,
height: mwInfo.width*0.052,
borderWidth: 1,
cornerRadius: 5,
isModal: true,
@ -52,8 +52,8 @@ export struct TitleColumnSub {
this.viewDialog=this.ViewDialog();
}
this.viewDialog.open();
}).width(mwInfo.mWinWidth*0.01)
.height(mwInfo.mWinWidth*0.01)
}).width(mwInfo.width*0.01)
.height(mwInfo.height*0.01)
.backgroundColor(Color.Transparent)
.backgroundImage($r('app.media.' + SwitchView[0].eIcon))
.backgroundImageSize({

View File

@ -2,9 +2,9 @@ import { hilog } from '@kit.PerformanceAnalysisKit';
import {TitleTabData, TitleModel} from '../LayoutInterface/Layout/TitleTabData'
import { FileMenuData } from "../LayoutInterface/Layout/FileMenuData";
import {TitleTabContent} from './TitleTabContent'
import { mwInfo } from '../AppStorageV2Class';
import { mwInfo } from '../DispWinInfo/DispWinInfo'
import { TitleButton } from '../LayoutInterface/Interface/ButtonInterface';
import { BaseMenu } from '../CustomStyle/Menu';
import { BaseMenu } from '../CustomController/Menu';
@Entry
@ComponentV2
@ -25,8 +25,8 @@ export struct TitleTab {
Button((FileMenuData.aMenus[0] as TitleButton).eName)
.fontSize(16)
.fontColor(Color.Black)
.height(mwInfo.mWinHeight*0.025)
.width(mwInfo.mWinWidth*0.035)
.height(mwInfo.height*0.025)
.width(mwInfo.width*0.035)
.bindMenu(BaseMenu(FileMenuData))
.type(ButtonType.Normal)
.backgroundColor('#f3f3f0')
@ -36,8 +36,8 @@ export struct TitleTab {
.fontSize(16)
.fontColor(Color.Black)
.fontWeight(index === this.titleBarFocusIndex ? FontWeight.Bold : FontWeight.Normal)
.height(mwInfo.mWinHeight*0.025)
.width(mwInfo.mWinWidth*0.035)
.height(mwInfo.height*0.025)
.width(mwInfo.width*0.035)
.type(ButtonType.Normal)
.backgroundColor('#f3f3f0')
.onClick(() => {
@ -69,6 +69,6 @@ export struct TitleTab {
}.scrollable(true)
.barHeight(0)
.barMode(BarMode.Fixed)
}.width(mwInfo.mWinWidth)
}.width(mwInfo.width)
}
}

View File

@ -1,8 +1,8 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { TitleButton} from '../LayoutInterface/Interface/ButtonInterface';
import { TitleGroup} from '../LayoutInterface/Interface/GroupInterface';
import {GroupTextEventMenu} from '../CustomStyle/Menu'
import {EventBtn,MenuBtn} from '../CustomStyle/Button'
import {GroupTextEventMenu} from '../CustomController/Menu'
import {EventBtn,MenuBtn} from '../CustomController/Button'
import { TitleModel } from '../LayoutInterface/Layout/TitleTabData';
@ComponentV2

View File

@ -5,14 +5,15 @@
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"2in1"
"2in1",
"tablet"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"requestPermissions": [
{
"name": "ohos.permission.INPUT_MONITORING"
"name": "ohos.permission.INPUT_MONITORING",
}
],
"abilities": [