diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/test/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading.test.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/test/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ec3f9f57fef8f11535f05b763f3492ed01e8ad3 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/test/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading.test.ets @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect, Level } from '@ohos/hypium' +import Settings from '../model/Settings' +import windowSnap from '../model/snapShot' +import Logger from '../model/Logger' +import Utils from '../model/Utils' +import { Driver, ON,Component ,MouseButton } from '@ohos.UiTest' +/* + * SUB_ACE_UI_ATTRIBUTES_FONT_INTERFACE_0010:设置文本颜色 + * + * Settings.createWindow(config.url): + * 创建窗口,更改窗口基本配置,更改方式详见model/Settings createWindow方法 + * + * windowSnap.snapShot(globalThis.context): + * 窗口截屏&图片文件保存,存储在设备端 + * 存储文件固定,单挑用例执行后覆盖,用于自动化UI对比 + * 支持调试更改文件名为时间戳格式,更改model/snapShot createAndGetFile方法 注释L35,放开L32,L33 + * + * Logger日志使用方法: + * import Logger form './model/Logger' + * Logger.info(TAG,`config = ${config}, err = ${JSON.stringify(exception)}`) + * */ + +export default function UiComponentTextRichEditorHalfLeading() { + + describe('UiComponentTextRichEditorHalfLeading', () => { + afterEach(async (done: Function) => { + if (Settings.windowClass == undefined) { + return + } + + Settings.windowClass.destroyWindow((err) => { + if (err.code) { + Logger.error('TEST', `Failed to destroy the window. Cause : ${JSON.stringify(err)}`) + return; + } + Logger.info('TEST', `Succeeded in destroy the window.`); + }) + await Utils.sleep(1000); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0010 + * @tc.name Use addTextCpan to add text content for setting half leading + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0010', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0010 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading01") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorHalfLeading01'),1000); + let point = await richeditor.getBoundsCenter(); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await driver.mouseScroll({x:point.x, y:point.y}, true, 30) + windowSnap.snapShot() + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0010 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0003 + * @tc.name Use addTextCpan to add text content for setting half leading + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0003', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0003 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading02") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorHalfLeading02'),1000); + let point = await richeditor.getBoundsCenter(); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await driver.mouseScroll({x:point.x, y:point.y}, true, 30) + windowSnap.snapShot() + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0003 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0007 + * @tc.name Dynamically setting up halfleading + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0007', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0007 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading03") + let driver:Driver=Driver.create(); + let button: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorHalfLeading03_02'),1000); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await button.click(); + windowSnap.snapShot() + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0007 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0008 + * @tc.name Dynamically setting up lineHeight + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0008', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0008 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading04") + let driver:Driver=Driver.create(); + let button: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorHalfLeading04_02'),1000); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await button.click(); + windowSnap.snapShot() + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0008 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0004 + * @tc.name Set halfLeading to null/undefined + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0004', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0004 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading05") + let driver:Driver=Driver.create(); + let button: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorHalfLeading05_02'),1000); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await button.click(); + windowSnap.snapShot() + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0004 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0005 + * @tc.name Image text mixing, halfleading only applies to text + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0005', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0005 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading06") + let driver:Driver=Driver.create(); + let button: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorHalfLeading06_02'),1000); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await button.click(); + windowSnap.snapShot() + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0005 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0006 + * @tc.name Add decorative lines to the text and set halfLeading to true + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0006', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0006 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading07") + let driver:Driver=Driver.create(); + let button: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorHalfLeading07_02'),1000); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await button.click(); + windowSnap.snapShot() + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_HALFLEADING_0006 finish.`); + done() + }) + }) +} diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/test/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder.test.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/test/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..7923350c4a210768229e3fd810c25cfa8d9f6f6c --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/test/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder.test.ets @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect, Level } from '@ohos/hypium' +import Settings from '../model/Settings' +import windowSnap from '../model/snapShot' +import Logger from '../model/Logger' +import Utils from '../model/Utils' +import { Driver, ON,Component ,MouseButton } from '@ohos.UiTest' +/* + * SUB_ACE_UI_ATTRIBUTES_FONT_INTERFACE_0010:设置文本颜色 + * + * Settings.createWindow(config.url): + * 创建窗口,更改窗口基本配置,更改方式详见model/Settings createWindow方法 + * + * windowSnap.snapShot(globalThis.context): + * 窗口截屏&图片文件保存,存储在设备端 + * 存储文件固定,单挑用例执行后覆盖,用于自动化UI对比 + * 支持调试更改文件名为时间戳格式,更改model/snapShot createAndGetFile方法 注释L35,放开L32,L33 + * + * Logger日志使用方法: + * import Logger form './model/Logger' + * Logger.info(TAG,`config = ${config}, err = ${JSON.stringify(exception)}`) + * */ + +export default function UiComponentTextRichEditorMenuBuilder() { + + describe('UiComponentTextRichEditorMenuBuilder', () => { + afterEach(async (done: Function) => { + if (Settings.windowClass == undefined) { + return + } + + Settings.windowClass.destroyWindow((err) => { + if (err.code) { + Logger.error('TEST', `Failed to destroy the window. Cause : ${JSON.stringify(err)}`) + return; + } + Logger.info('TEST', `Succeeded in destroy the window.`); + }) + await Utils.sleep(1000); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0007 + * @tc.name Long press/right-click/select builderSpan and other content, bind custom menu type as TEXT + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0007', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0007 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder01") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder01'),1000); + let point = await richeditor.getBoundsCenter() + await richeditor.longClick(); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+70},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + windowSnap.snapShot() + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0007 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0009 + * @tc.name Long press/right-click/select builderSpan and other content, bind custom menu type as BUILDER + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0009', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0009 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder02") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder02'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0009 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0004 + * @tc.name Long press/right-click/select builderSpan with the mouse, bind the custom menu type as Mixed + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0004', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0004 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder03") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder03'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0004 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0001 + * @tc.name Long press/right-click/select builderSpan with the mouse, bind custom menu type as TEXT + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0001', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0001 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder04") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder04'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1500) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0001 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0002 + * @tc.name Long press/right-click/select builderSpan with the mouse, bind custom menu type as IMAGE + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0002', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0002 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder05") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder05'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0002 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0006 + * @tc.name Long press/right-click/select builderSpan with the mouse, bind custom menu type as IMAGE + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0006', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0006 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder06") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder06'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0006 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0005 + * @tc.name Long press/right-click/select builderSpan with the mouse to bind multiple custom menus, including BUILDER + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0005', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0005 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder07") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder07'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0005 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0008 + * @tc.name Long press/right-click/select builderSpan and other content, bind custom menu type as IMAGE + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0008', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0008 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder08") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder08'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0008 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0010 + * @tc.name Long press/right-click/select builderSpan and other content with the mouse, bind custom menu type as Mixed + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0010', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0010 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder09") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder09'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0010 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0012 + * @tc.name Long press/right-click/select builderSpan and other content, bind multiple custom menus, types do not include Mixed + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0012', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0012 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder10") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder10'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0012 finish.`); + done() + }) + + /* + * @tc.number SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0011 + * @tc.name Long press/right-click/select builderSpan and other content, bind multiple custom menus, types include Mixed + * @tc.desc Function test + * @tc.size MediumTest + * @tc.type Function + * @tc.level 0 + */ + it('SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0011', Level.LEVEL0, async (done: Function) => { + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0011 start.`); + Settings.createWindow("testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder11") + let driver:Driver=Driver.create(); + let richeditor: Component = await driver.waitForComponent(ON.id('UiComponentTextRichEditorMenuBuilder11'),1000); + let point = await richeditor.getBoundsCenter() + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_RIGHT); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await driver.mouseClick({x:point.x, y:point.y}, MouseButton.MOUSE_BUTTON_LEFT); + await richeditor.longClick(); + windowSnap.snapShot() + await Utils.sleep(1000) + await driver.click(point.x+200,point.y+70) + await driver.waitForIdle(500,2000) + await driver.mouseDrag({x:point.x+200, y:point.y+60},{x:point.x-200, y:point.y-70},600); + windowSnap.snapShot() + await driver.waitForIdle(500,2000) + await Utils.sleep(1000) + Logger.info('TEST', `SUB_ACE_UI_COMPONENT_TEXT_RICHEDITOR_MENU_BUILDER_0011 finish.`); + done() + }) + }) +} diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading01.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading01.ets new file mode 100644 index 0000000000000000000000000000000000000000..69809304e025711f65714b69a70a6a25d2cd9d39 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading01.ets @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const halfleadingcanvasWidth = 1000; +const halfleadingcanvasHeight = 100; +const halfleadingIndentation = 40; +class halfleadingLeadingMarginCreator { + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(halfleadingcanvasWidth, halfleadingcanvasHeight); + private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings); + public static instance: halfleadingLeadingMarginCreator = new halfleadingLeadingMarginCreator(); + + public getFontSizeLevel(fontSize: number) { + const fontScaled: number = Number(fontSize) / 16; + + enum FontSizeScaleThreshold { + SMALL = 0.9, + NORMAL = 1.1, + LEVEL_1_LARGE = 1.2, + LEVEL_2_LARGE = 1.4, + LEVEL_3_LARGE = 1.5 + } + + let fontSizeLevel: number = 1; + + if (fontScaled < FontSizeScaleThreshold.SMALL) { + fontSizeLevel = 0; + } else if (fontScaled < FontSizeScaleThreshold.NORMAL) { + fontSizeLevel = 1; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) { + fontSizeLevel = 2; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) { + fontSizeLevel = 3; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) { + fontSizeLevel = 4; + } else { + fontSizeLevel = 1; + } + + return fontSizeLevel; + } + + public getmarginLevel(Width: number) { + let marginlevel: number = 1; + if (Width == 40) { + marginlevel = 2.0; + } else if (Width == 80) { + marginlevel = 1.0; + } else if (Width == 120) { + marginlevel = 2/3; + } else if (Width == 160) { + marginlevel = 0.5; + } else if (Width == 200) { + marginlevel = 0.4; + } + return marginlevel; + } + + public genStrMark(fontSize: number, str: string): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + this.offContext.font = fontSize + 'vp sans-serif'; + this.offContext.fillText(str + '.', 0, fontSize * 0.9) + return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize) + } + + public genSquareMark(fontSize: number): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + const coordinate = fontSize * (1 - 1 / 1.5) / 2; + const sideLength = fontSize / 1.5; + this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength) + return this.offContext.getPixelMap(0, 0, fontSize, fontSize) + } + + public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap { + const indentLevel = level ?? 1; + const offsetLevel = [22, 28, 32, 34, 38]; + const fontSizeLevel = this.getFontSizeLevel(fontSize); + const marginlevel = this.getmarginLevel(width); + const newCanvas = new OffscreenCanvas(halfleadingcanvasWidth, halfleadingcanvasHeight); + const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings); + const centerCoordinate = 50; + const radius = 10; + this.clearCanvas() + newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI) + newOffContext.fillStyle = '66FF0000'; + newOffContext.fill() + return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100) + } + + private clearCanvas() { + this.offContext.clearRect(0, 0, halfleadingcanvasWidth, halfleadingcanvasHeight) + } +} + +@Entry +@Component +struct UiComponentTextRichEditorHalfLeading01 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + private leadingMarkCreatorInstance = halfleadingLeadingMarginCreator.instance; + private fontNameRawFile: string = 'MiSans-Bold'; + @State fs: number = 30; + @State cl: number = Color.Black; + private leftMargin: Dimension = 0; + private richEditorTextStyle: RichEditorTextStyle = {}; + + aboutToAppear() { + this.getUIContext().getFont().registerFont({ + familyName: 'MiSans-Bold', + familySrc: '/font/MiSans-Bold.ttf' + }) + } + + build() { + Scroll() { + Column() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan("set halfLeading to true\n", + { + style: + { + halfLeading: true, + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + this.controller.addTextSpan("set halfLeading to false\n", + { + style: + { + halfLeading: false, + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + }) + .id('UiComponentTextRichEditorHalfLeading01') + .height(200) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + + Row({ space: 5 }) { + Button('setTypingStyle1') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Blue, + fontSize: 50, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + }) + }) + + Button('setTypingStyle2') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: FontWeight.Lighter, + fontColor: Color.Green, + fontSize: 16, + fontStyle: FontStyle.Normal, + decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } + }) + }) + } + Divider() + Button("getTypingStyle").onClick(() => { + this.richEditorTextStyle = this.controller.getTypingStyle(); + console.info("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle)); + }) + Divider() + Row({ space: 5 }) { + Button("向右列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + + Button("向左列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin > 0) { + margin -= halfleadingIndentation; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + } + Divider() + Row({ space: 5 }) { + Button("向右空白缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + + Button("向左空白缩进").onClick(() => { + let margin = Number(this.leftMargin) + if (margin > 0) { + margin -= halfleadingIndentation; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading02.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading02.ets new file mode 100644 index 0000000000000000000000000000000000000000..22692c35a95c0d445fea3e0e814ef221cc550baa --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading02.ets @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const halfleadingcanvasWidth2 = 1000; +const halfleadingcanvasHeight2 = 100; +const halfleadingIndentation2 = 40; +class halfleadingLeadingMarginCreator2 { + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(halfleadingcanvasWidth2, halfleadingcanvasHeight2); + private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings); + public static instance: halfleadingLeadingMarginCreator2 = new halfleadingLeadingMarginCreator2(); + + public getFontSizeLevel(fontSize: number) { + const fontScaled: number = Number(fontSize) / 16; + + enum FontSizeScaleThreshold { + SMALL = 0.9, + NORMAL = 1.1, + LEVEL_1_LARGE = 1.2, + LEVEL_2_LARGE = 1.4, + LEVEL_3_LARGE = 1.5 + } + + let fontSizeLevel: number = 1; + + if (fontScaled < FontSizeScaleThreshold.SMALL) { + fontSizeLevel = 0; + } else if (fontScaled < FontSizeScaleThreshold.NORMAL) { + fontSizeLevel = 1; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) { + fontSizeLevel = 2; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) { + fontSizeLevel = 3; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) { + fontSizeLevel = 4; + } else { + fontSizeLevel = 1; + } + + return fontSizeLevel; + } + + public getmarginLevel(Width: number) { + let marginlevel: number = 1; + if (Width == 40) { + marginlevel = 2.0; + } else if (Width == 80) { + marginlevel = 1.0; + } else if (Width == 120) { + marginlevel = 2/3; + } else if (Width == 160) { + marginlevel = 0.5; + } else if (Width == 200) { + marginlevel = 0.4; + } + return marginlevel; + } + + public genStrMark(fontSize: number, str: string): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + this.offContext.font = fontSize + 'vp sans-serif'; + this.offContext.fillText(str + '.', 0, fontSize * 0.9) + return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize) + } + + public genSquareMark(fontSize: number): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + const coordinate = fontSize * (1 - 1 / 1.5) / 2; + const sideLength = fontSize / 1.5; + this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength) + return this.offContext.getPixelMap(0, 0, fontSize, fontSize) + } + + public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap { + const indentLevel = level ?? 1; + const offsetLevel = [22, 28, 32, 34, 38]; + const fontSizeLevel = this.getFontSizeLevel(fontSize); + const marginlevel = this.getmarginLevel(width); + const newCanvas = new OffscreenCanvas(halfleadingcanvasWidth2, halfleadingcanvasHeight2); + const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings); + const centerCoordinate = 50; + const radius = 10; + this.clearCanvas() + newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI) + newOffContext.fillStyle = '66FF0000'; + newOffContext.fill() + return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100) + } + + private clearCanvas() { + this.offContext.clearRect(0, 0, halfleadingcanvasWidth2, halfleadingcanvasHeight2) + } +} + +@Entry +@Component +struct UiComponentTextRichEditorHalfLeading02 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + private leadingMarkCreatorInstance = halfleadingLeadingMarginCreator2.instance; + private fontNameRawFile: string = 'MiSans-Bold'; + @State fs: number = 30; + @State cl: number = Color.Black; + private leftMargin: Dimension = 0; + private richEditorTextStyle: RichEditorTextStyle = {}; + + aboutToAppear() { + this.getUIContext().getFont().registerFont({ + familyName: 'MiSans-Bold', + familySrc: '/font/MiSans-Bold.ttf' + }) + } + + build() { + Scroll() { + Column() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan("set halfLeading to true\n", + { + style: + { + halfLeading: true, + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + this.controller.addTextSpan("not set halfLeading\n", + { + style: + { + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + }) + .id('UiComponentTextRichEditorHalfLeading02') + .height(192) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + + Row({ space: 5 }) { + Button('setTypingStyle1') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Blue, + fontSize: 50, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + }) + }) + + Button('setTypingStyle2') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: FontWeight.Lighter, + fontColor: Color.Green, + fontSize: 16, + fontStyle: FontStyle.Normal, + decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } + }) + }) + } + Divider() + Button("getTypingStyle").onClick(() => { + this.richEditorTextStyle = this.controller.getTypingStyle(); + console.info("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle)); + }) + Divider() + Row({ space: 5 }) { + Button("向右列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation2; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + + Button("向左列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin > 0) { + margin -= halfleadingIndentation2; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + } + Divider() + Row({ space: 5 }) { + Button("向右空白缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation2; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + + Button("向左空白缩进").onClick(() => { + let margin = Number(this.leftMargin) + if (margin > 0) { + margin -= halfleadingIndentation2; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading03.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading03.ets new file mode 100644 index 0000000000000000000000000000000000000000..b1d436bfd90419d21ee0bebaf0429d7a7b60bc3e --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading03.ets @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const halfleadingcanvasWidth3 = 1000; +const halfleadingcanvasHeight3 = 100; +const halfleadingIndentation3 = 40; +class halfleadingLeadingMarginCreator3 { + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(halfleadingcanvasWidth3, halfleadingcanvasHeight3); + private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings); + public static instance: halfleadingLeadingMarginCreator3 = new halfleadingLeadingMarginCreator3(); + + public getFontSizeLevel(fontSize: number) { + const fontScaled: number = Number(fontSize) / 16; + + enum FontSizeScaleThreshold { + SMALL = 0.9, + NORMAL = 1.1, + LEVEL_1_LARGE = 1.2, + LEVEL_2_LARGE = 1.4, + LEVEL_3_LARGE = 1.5 + } + + let fontSizeLevel: number = 1; + + if (fontScaled < FontSizeScaleThreshold.SMALL) { + fontSizeLevel = 0; + } else if (fontScaled < FontSizeScaleThreshold.NORMAL) { + fontSizeLevel = 1; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) { + fontSizeLevel = 2; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) { + fontSizeLevel = 3; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) { + fontSizeLevel = 4; + } else { + fontSizeLevel = 1; + } + + return fontSizeLevel; + } + + public getmarginLevel(Width: number) { + let marginlevel: number = 1; + if (Width == 40) { + marginlevel = 2.0; + } else if (Width == 80) { + marginlevel = 1.0; + } else if (Width == 120) { + marginlevel = 2/3; + } else if (Width == 160) { + marginlevel = 0.5; + } else if (Width == 200) { + marginlevel = 0.4; + } + return marginlevel; + } + + public genStrMark(fontSize: number, str: string): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + this.offContext.font = fontSize + 'vp sans-serif'; + this.offContext.fillText(str + '.', 0, fontSize * 0.9) + return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize) + } + + public genSquareMark(fontSize: number): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + const coordinate = fontSize * (1 - 1 / 1.5) / 2; + const sideLength = fontSize / 1.5; + this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength) + return this.offContext.getPixelMap(0, 0, fontSize, fontSize) + } + + public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap { + const indentLevel = level ?? 1; + const offsetLevel = [22, 28, 32, 34, 38]; + const fontSizeLevel = this.getFontSizeLevel(fontSize); + const marginlevel = this.getmarginLevel(width); + const newCanvas = new OffscreenCanvas(halfleadingcanvasWidth3, halfleadingcanvasHeight3); + const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings); + const centerCoordinate = 50; + const radius = 10; + this.clearCanvas() + newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI) + newOffContext.fillStyle = '66FF0000'; + newOffContext.fill() + return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100) + } + + private clearCanvas() { + this.offContext.clearRect(0, 0, halfleadingcanvasWidth3, halfleadingcanvasHeight3) + } +} + +@Entry +@Component +struct UiComponentTextRichEditorHalfLeading03 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + private leadingMarkCreatorInstance = halfleadingLeadingMarginCreator3.instance; + private fontNameRawFile: string = 'MiSans-Bold'; + @State fs: number = 30; + @State cl: number = Color.Black; + private leftMargin: Dimension = 0; + private richEditorTextStyle: RichEditorTextStyle = {}; + + aboutToAppear() { + this.getUIContext().getFont().registerFont({ + familyName: 'MiSans-Bold', + familySrc: '/font/MiSans-Bold.ttf' + }) + } + + build() { + Scroll() { + Column() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan("hello world\n", + { + style: + { + halfLeading: true, + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + }) + .id('UiComponentTextRichEditorHalfLeading03_01') + .height(200) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + + Row({ space: 5 }) { + Button('change halfleading') + .fontSize(12) + .onClick(() => { + this.controller.updateSpanStyle({ + start: 0, + textStyle: + { + halfLeading: false + }, + }) + }) + .id('UiComponentTextRichEditorHalfLeading03_02') + } + Divider() + Row({ space: 5 }) { + Button('setTypingStyle1') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Blue, + fontSize: 50, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + }) + }) + + Button('setTypingStyle2') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: FontWeight.Lighter, + fontColor: Color.Green, + fontSize: 16, + fontStyle: FontStyle.Normal, + decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } + }) + }) + } + Divider() + Button("getTypingStyle").onClick(() => { + this.richEditorTextStyle = this.controller.getTypingStyle(); + console.info("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle)); + }) + Divider() + Row({ space: 5 }) { + Button("向右列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation3; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + + Button("向左列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin > 0) { + margin -= halfleadingIndentation3; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + } + Divider() + Row({ space: 5 }) { + Button("向右空白缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation3; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + + Button("向左空白缩进").onClick(() => { + let margin = Number(this.leftMargin) + if (margin > 0) { + margin -= halfleadingIndentation3; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading04.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading04.ets new file mode 100644 index 0000000000000000000000000000000000000000..6ffeca5833383ad2e389467f85ff422f9e6288b5 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading04.ets @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const halfleadingcanvasWidth4 = 1000; +const halfleadingcanvasHeight4 = 100; +const halfleadingIndentation4 = 40; +class halfleadingLeadingMarginCreator4 { + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(halfleadingcanvasWidth4, halfleadingcanvasHeight4); + private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings); + public static instance: halfleadingLeadingMarginCreator4 = new halfleadingLeadingMarginCreator4(); + + public getFontSizeLevel(fontSize: number) { + const fontScaled: number = Number(fontSize) / 16; + + enum FontSizeScaleThreshold { + SMALL = 0.9, + NORMAL = 1.1, + LEVEL_1_LARGE = 1.2, + LEVEL_2_LARGE = 1.4, + LEVEL_3_LARGE = 1.5 + } + + let fontSizeLevel: number = 1; + + if (fontScaled < FontSizeScaleThreshold.SMALL) { + fontSizeLevel = 0; + } else if (fontScaled < FontSizeScaleThreshold.NORMAL) { + fontSizeLevel = 1; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) { + fontSizeLevel = 2; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) { + fontSizeLevel = 3; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) { + fontSizeLevel = 4; + } else { + fontSizeLevel = 1; + } + + return fontSizeLevel; + } + + public getmarginLevel(Width: number) { + let marginlevel: number = 1; + if (Width == 40) { + marginlevel = 2.0; + } else if (Width == 80) { + marginlevel = 1.0; + } else if (Width == 120) { + marginlevel = 2/3; + } else if (Width == 160) { + marginlevel = 0.5; + } else if (Width == 200) { + marginlevel = 0.4; + } + return marginlevel; + } + + public genStrMark(fontSize: number, str: string): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + this.offContext.font = fontSize + 'vp sans-serif'; + this.offContext.fillText(str + '.', 0, fontSize * 0.9) + return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize) + } + + public genSquareMark(fontSize: number): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + const coordinate = fontSize * (1 - 1 / 1.5) / 2; + const sideLength = fontSize / 1.5; + this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength) + return this.offContext.getPixelMap(0, 0, fontSize, fontSize) + } + + public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap { + const indentLevel = level ?? 1; + const offsetLevel = [22, 28, 32, 34, 38]; + const fontSizeLevel = this.getFontSizeLevel(fontSize); + const marginlevel = this.getmarginLevel(width); + const newCanvas = new OffscreenCanvas(halfleadingcanvasWidth4, halfleadingcanvasHeight4); + const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings); + const centerCoordinate = 50; + const radius = 10; + this.clearCanvas() + newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI) + newOffContext.fillStyle = '66FF0000'; + newOffContext.fill() + return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100) + } + + private clearCanvas() { + this.offContext.clearRect(0, 0, halfleadingcanvasWidth4, halfleadingcanvasHeight4) + } +} + +@Entry +@Component +struct UiComponentTextRichEditorHalfLeading04 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + private leadingMarkCreatorInstance = halfleadingLeadingMarginCreator4.instance; + private fontNameRawFile: string = 'MiSans-Bold'; + @State fs: number = 30; + @State cl: number = Color.Black; + private leftMargin: Dimension = 0; + private richEditorTextStyle: RichEditorTextStyle = {}; + + aboutToAppear() { + this.getUIContext().getFont().registerFont({ + familyName: 'MiSans-Bold', + familySrc: '/font/MiSans-Bold.ttf' + }) + } + + build() { + Scroll() { + Column() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan("hello world\n", + { + style: + { + halfLeading: true, + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + }) + .id('UiComponentTextRichEditorHalfLeading04_01') + .height(200) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + + Row({ space: 5 }) { + Button('change lineheight') + .fontSize(12) + .onClick(() => { + this.controller.updateSpanStyle({ + start: 0, + textStyle: + { + lineHeight: 160 + }, + }) + }) + .id('UiComponentTextRichEditorHalfLeading04_02') + } + Divider() + Row({ space: 5 }) { + Button('setTypingStyle1') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Blue, + fontSize: 50, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + }) + }) + + Button('setTypingStyle2') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: FontWeight.Lighter, + fontColor: Color.Green, + fontSize: 16, + fontStyle: FontStyle.Normal, + decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } + }) + }) + } + Divider() + Button("getTypingStyle").onClick(() => { + this.richEditorTextStyle = this.controller.getTypingStyle(); + console.info("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle)); + }) + Divider() + Row({ space: 5 }) { + Button("向右列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation4; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + + Button("向左列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin > 0) { + margin -= halfleadingIndentation4; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + } + Divider() + Row({ space: 5 }) { + Button("向右空白缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation4; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + + Button("向左空白缩进").onClick(() => { + let margin = Number(this.leftMargin) + if (margin > 0) { + margin -= halfleadingIndentation4; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading05.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading05.ets new file mode 100644 index 0000000000000000000000000000000000000000..7c388cf0fa966de0311201f1442281e49ffc4eed --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading05.ets @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const halfleadingcanvasWidth5 = 1000; +const halfleadingcanvasHeight5 = 100; +const halfleadingIndentation5 = 40; +class halfleadingLeadingMarginCreator5 { + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(halfleadingcanvasWidth5, halfleadingcanvasHeight5); + private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings); + public static instance: halfleadingLeadingMarginCreator5 = new halfleadingLeadingMarginCreator5(); + + public getFontSizeLevel(fontSize: number) { + const fontScaled: number = Number(fontSize) / 16; + + enum FontSizeScaleThreshold { + SMALL = 0.9, + NORMAL = 1.1, + LEVEL_1_LARGE = 1.2, + LEVEL_2_LARGE = 1.4, + LEVEL_3_LARGE = 1.5 + } + + let fontSizeLevel: number = 1; + + if (fontScaled < FontSizeScaleThreshold.SMALL) { + fontSizeLevel = 0; + } else if (fontScaled < FontSizeScaleThreshold.NORMAL) { + fontSizeLevel = 1; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) { + fontSizeLevel = 2; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) { + fontSizeLevel = 3; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) { + fontSizeLevel = 4; + } else { + fontSizeLevel = 1; + } + + return fontSizeLevel; + } + + public getmarginLevel(Width: number) { + let marginlevel: number = 1; + if (Width == 40) { + marginlevel = 2.0; + } else if (Width == 80) { + marginlevel = 1.0; + } else if (Width == 120) { + marginlevel = 2/3; + } else if (Width == 160) { + marginlevel = 0.5; + } else if (Width == 200) { + marginlevel = 0.4; + } + return marginlevel; + } + + public genStrMark(fontSize: number, str: string): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + this.offContext.font = fontSize + 'vp sans-serif'; + this.offContext.fillText(str + '.', 0, fontSize * 0.9) + return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize) + } + + public genSquareMark(fontSize: number): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + const coordinate = fontSize * (1 - 1 / 1.5) / 2; + const sideLength = fontSize / 1.5; + this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength) + return this.offContext.getPixelMap(0, 0, fontSize, fontSize) + } + + public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap { + const indentLevel = level ?? 1; + const offsetLevel = [22, 28, 32, 34, 38]; + const fontSizeLevel = this.getFontSizeLevel(fontSize); + const marginlevel = this.getmarginLevel(width); + const newCanvas = new OffscreenCanvas(halfleadingcanvasWidth5, halfleadingcanvasHeight5); + const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings); + const centerCoordinate = 50; + const radius = 10; + this.clearCanvas() + newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI) + newOffContext.fillStyle = '66FF0000'; + newOffContext.fill() + return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100) + } + + private clearCanvas() { + this.offContext.clearRect(0, 0, halfleadingcanvasWidth5, halfleadingcanvasHeight5) + } +} + +@Entry +@Component +struct UiComponentTextRichEditorHalfLeading05 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + private leadingMarkCreatorInstance = halfleadingLeadingMarginCreator5.instance; + private fontNameRawFile: string = 'MiSans-Bold'; + @State fs: number = 30; + @State cl: number = Color.Black; + private leftMargin: Dimension = 0; + private richEditorTextStyle: RichEditorTextStyle = {}; + + aboutToAppear() { + this.getUIContext().getFont().registerFont({ + familyName: 'MiSans-Bold', + familySrc: '/font/MiSans-Bold.ttf' + }) + } + + build() { + Scroll() { + Column() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan("hello world\n", + { + style: + { + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + }) + .id('UiComponentTextRichEditorHalfLeading05_01') + .height(200) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + + Row({ space: 5 }) { + Button('change halfleading to null') + .fontSize(12) + .onClick(() => { + this.controller.updateSpanStyle({ + start: 0, + textStyle: + { + halfLeading: undefined + }, + }) + }) + .id('UiComponentTextRichEditorHalfLeading05_02') + } + Divider() + Row({ space: 5 }) { + Button('setTypingStyle1') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Blue, + fontSize: 50, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + }) + }) + + Button('setTypingStyle2') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: FontWeight.Lighter, + fontColor: Color.Green, + fontSize: 16, + fontStyle: FontStyle.Normal, + decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } + }) + }) + } + Divider() + Button("getTypingStyle").onClick(() => { + this.richEditorTextStyle = this.controller.getTypingStyle(); + console.info("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle)); + }) + Divider() + Row({ space: 5 }) { + Button("向右列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation5; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + + Button("向左列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin > 0) { + margin -= halfleadingIndentation5; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + } + Divider() + Row({ space: 5 }) { + Button("向右空白缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation5; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + + Button("向左空白缩进").onClick(() => { + let margin = Number(this.leftMargin) + if (margin > 0) { + margin -= halfleadingIndentation5; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading06.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading06.ets new file mode 100644 index 0000000000000000000000000000000000000000..6b6236a2df1db3e45ae92e7dea382ab5635a5a37 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading06.ets @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const halfleadingcanvasWidth6 = 1000; +const halfleadingcanvasHeight6 = 100; +const halfleadingIndentation6 = 40; +class halfleadingLeadingMarginCreator6 { + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(halfleadingcanvasWidth6, halfleadingcanvasHeight6); + private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings); + public static instance: halfleadingLeadingMarginCreator6 = new halfleadingLeadingMarginCreator6(); + + public getFontSizeLevel(fontSize: number) { + const fontScaled: number = Number(fontSize) / 16; + + enum FontSizeScaleThreshold { + SMALL = 0.9, + NORMAL = 1.1, + LEVEL_1_LARGE = 1.2, + LEVEL_2_LARGE = 1.4, + LEVEL_3_LARGE = 1.5 + } + + let fontSizeLevel: number = 1; + + if (fontScaled < FontSizeScaleThreshold.SMALL) { + fontSizeLevel = 0; + } else if (fontScaled < FontSizeScaleThreshold.NORMAL) { + fontSizeLevel = 1; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) { + fontSizeLevel = 2; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) { + fontSizeLevel = 3; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) { + fontSizeLevel = 4; + } else { + fontSizeLevel = 1; + } + + return fontSizeLevel; + } + + public getmarginLevel(Width: number) { + let marginlevel: number = 1; + if (Width == 40) { + marginlevel = 2.0; + } else if (Width == 80) { + marginlevel = 1.0; + } else if (Width == 120) { + marginlevel = 2/3; + } else if (Width == 160) { + marginlevel = 0.5; + } else if (Width == 200) { + marginlevel = 0.4; + } + return marginlevel; + } + + public genStrMark(fontSize: number, str: string): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + this.offContext.font = fontSize + 'vp sans-serif'; + this.offContext.fillText(str + '.', 0, fontSize * 0.9) + return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize) + } + + public genSquareMark(fontSize: number): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + const coordinate = fontSize * (1 - 1 / 1.5) / 2; + const sideLength = fontSize / 1.5; + this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength) + return this.offContext.getPixelMap(0, 0, fontSize, fontSize) + } + + public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap { + const indentLevel = level ?? 1; + const offsetLevel = [22, 28, 32, 34, 38]; + const fontSizeLevel = this.getFontSizeLevel(fontSize); + const marginlevel = this.getmarginLevel(width); + const newCanvas = new OffscreenCanvas(halfleadingcanvasWidth6, halfleadingcanvasHeight6); + const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings); + const centerCoordinate = 50; + const radius = 10; + this.clearCanvas() + newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI) + newOffContext.fillStyle = '66FF0000'; + newOffContext.fill() + return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100) + } + + private clearCanvas() { + this.offContext.clearRect(0, 0, halfleadingcanvasWidth6, halfleadingcanvasHeight6) + } +} + +@Entry +@Component +struct UiComponentTextRichEditorHalfLeading06 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + private leadingMarkCreatorInstance = halfleadingLeadingMarginCreator6.instance; + private fontNameRawFile: string = 'MiSans-Bold'; + @State fs: number = 30; + @State cl: number = Color.Black; + private leftMargin: Dimension = 0; + private richEditorTextStyle: RichEditorTextStyle = {}; + + aboutToAppear() { + this.getUIContext().getFont().registerFont({ + familyName: 'MiSans-Bold', + familySrc: '/font/MiSans-Bold.ttf' + }) + } + + build() { + Scroll() { + Column() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan("hello world", + { + style: + { + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + this.controller.addImageSpan(('/icon.png'), + { + imageStyle: + { + size: ["57px", "57px"] + } + }) + }) + .id('UiComponentTextRichEditorHalfLeading06_01') + .height(200) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + + Row({ space: 5 }) { + Button('change halfleading to null') + .fontSize(12) + .onClick(() => { + this.controller.updateSpanStyle({ + start: 0, + textStyle: + { + halfLeading: true + }, + }) + }) + .id('UiComponentTextRichEditorHalfLeading06_02') + } + Divider() + Row({ space: 5 }) { + Button('setTypingStyle1') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Blue, + fontSize: 50, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + }) + }) + + Button('setTypingStyle2') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: FontWeight.Lighter, + fontColor: Color.Green, + fontSize: 16, + fontStyle: FontStyle.Normal, + decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } + }) + }) + } + Divider() + Button("getTypingStyle").onClick(() => { + this.richEditorTextStyle = this.controller.getTypingStyle(); + console.info("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle)); + }) + Divider() + Row({ space: 5 }) { + Button("向右列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation6; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + + Button("向左列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin > 0) { + margin -= halfleadingIndentation6; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + } + Divider() + Row({ space: 5 }) { + Button("向右空白缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation6; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + + Button("向左空白缩进").onClick(() => { + let margin = Number(this.leftMargin) + if (margin > 0) { + margin -= halfleadingIndentation6; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading07.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading07.ets new file mode 100644 index 0000000000000000000000000000000000000000..c9827bb033908a9fff8c5db43651b26d2d25547d --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorHalfLeading/UiComponentTextRichEditorHalfLeading07.ets @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const halfleadingcanvasWidth7 = 1000; +const halfleadingcanvasHeight7 = 100; +const halfleadingIndentation7 = 40; +class halfleadingLeadingMarginCreator7 { + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(halfleadingcanvasWidth7, halfleadingcanvasHeight7); + private offContext: OffscreenCanvasRenderingContext2D = this.offscreenCanvas.getContext("2d", this.settings); + public static instance: halfleadingLeadingMarginCreator7 = new halfleadingLeadingMarginCreator7(); + + public getFontSizeLevel(fontSize: number) { + const fontScaled: number = Number(fontSize) / 16; + + enum FontSizeScaleThreshold { + SMALL = 0.9, + NORMAL = 1.1, + LEVEL_1_LARGE = 1.2, + LEVEL_2_LARGE = 1.4, + LEVEL_3_LARGE = 1.5 + } + + let fontSizeLevel: number = 1; + + if (fontScaled < FontSizeScaleThreshold.SMALL) { + fontSizeLevel = 0; + } else if (fontScaled < FontSizeScaleThreshold.NORMAL) { + fontSizeLevel = 1; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_1_LARGE) { + fontSizeLevel = 2; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_2_LARGE) { + fontSizeLevel = 3; + } else if (fontScaled < FontSizeScaleThreshold.LEVEL_3_LARGE) { + fontSizeLevel = 4; + } else { + fontSizeLevel = 1; + } + + return fontSizeLevel; + } + + public getmarginLevel(Width: number) { + let marginlevel: number = 1; + if (Width == 40) { + marginlevel = 2.0; + } else if (Width == 80) { + marginlevel = 1.0; + } else if (Width == 120) { + marginlevel = 2/3; + } else if (Width == 160) { + marginlevel = 0.5; + } else if (Width == 200) { + marginlevel = 0.4; + } + return marginlevel; + } + + public genStrMark(fontSize: number, str: string): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + this.offContext.font = fontSize + 'vp sans-serif'; + this.offContext.fillText(str + '.', 0, fontSize * 0.9) + return this.offContext.getPixelMap(0, 0, fontSize * (str.length + 1) / 1.75, fontSize) + } + + public genSquareMark(fontSize: number): PixelMap { + this.offContext = this.offscreenCanvas.getContext("2d", this.settings); + this.clearCanvas() + const coordinate = fontSize * (1 - 1 / 1.5) / 2; + const sideLength = fontSize / 1.5; + this.offContext.fillRect(coordinate, coordinate, sideLength, sideLength) + return this.offContext.getPixelMap(0, 0, fontSize, fontSize) + } + + public genCircleMark(fontSize: number, width: number, level?: number ): PixelMap { + const indentLevel = level ?? 1; + const offsetLevel = [22, 28, 32, 34, 38]; + const fontSizeLevel = this.getFontSizeLevel(fontSize); + const marginlevel = this.getmarginLevel(width); + const newCanvas = new OffscreenCanvas(halfleadingcanvasWidth7, halfleadingcanvasHeight7); + const newOffContext: OffscreenCanvasRenderingContext2D = newCanvas.getContext("2d", this.settings); + const centerCoordinate = 50; + const radius = 10; + this.clearCanvas() + newOffContext.ellipse(100 * (indentLevel + 1) - centerCoordinate * marginlevel, offsetLevel[fontSizeLevel], radius * marginlevel, radius, 0, 0, 2 * Math.PI) + newOffContext.fillStyle = '66FF0000'; + newOffContext.fill() + return newOffContext.getPixelMap(0, 0, 100 + 100 * indentLevel, 100) + } + + private clearCanvas() { + this.offContext.clearRect(0, 0, halfleadingcanvasWidth7, halfleadingcanvasHeight7) + } +} + +@Entry +@Component +struct UiComponentTextRichEditorHalfLeading07 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + private leadingMarkCreatorInstance = halfleadingLeadingMarginCreator7.instance; + private fontNameRawFile: string = 'MiSans-Bold'; + @State fs: number = 30; + @State cl: number = Color.Black; + private leftMargin: Dimension = 0; + private richEditorTextStyle: RichEditorTextStyle = {}; + + aboutToAppear() { + this.getUIContext().getFont().registerFont({ + familyName: 'MiSans-Bold', + familySrc: '/font/MiSans-Bold.ttf' + }) + } + + build() { + Scroll() { + Column() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan("hello world", + { + style: + { + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + } + }) + this.controller.addTextSpan("hello world", + { + style: + { + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.LineThrough, color: Color.Green } + } + }) + this.controller.addTextSpan("hello world", + { + style: + { + lineHeight:80, + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Red, + fontSize: 16, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Overline, color: Color.Green } + } + }) + }) + .id('UiComponentTextRichEditorHalfLeading07_01') + .height(200) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + + Row({ space: 5 }) { + Button('change halfleading to true and set decoration') + .fontSize(12) + .onClick(() => { + this.controller.updateSpanStyle({ + start: 0, + textStyle: + { + halfLeading: true + }, + }) + }) + .id('UiComponentTextRichEditorHalfLeading07_02') + } + Divider() + Row({ space: 5 }) { + Button('setTypingStyle1') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: 'medium', + fontFamily: this.fontNameRawFile, + fontColor: Color.Blue, + fontSize: 50, + fontStyle: FontStyle.Italic, + decoration: { type: TextDecorationType.Underline, color: Color.Green } + }) + }) + + Button('setTypingStyle2') + .fontSize(10) + .onClick(() => { + this.controller.setTypingStyle( + { + fontWeight: FontWeight.Lighter, + fontColor: Color.Green, + fontSize: 16, + fontStyle: FontStyle.Normal, + decoration: { type: TextDecorationType.Overline, color: 'rgba(169, 26, 246, 0.50)' } + }) + }) + } + Divider() + Button("getTypingStyle").onClick(() => { + this.richEditorTextStyle = this.controller.getTypingStyle(); + console.info("RichEditor getTypingStyle:" + JSON.stringify(this.richEditorTextStyle)); + }) + Divider() + Row({ space: 5 }) { + Button("向右列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation7; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + + Button("向左列表缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin > 0) { + margin -= halfleadingIndentation7; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin : { + pixelMap : this.leadingMarkCreatorInstance.genCircleMark(100, margin, 1), + size: [margin, 40] + } + } + }) + }) + } + Divider() + Row({ space: 5 }) { + Button("向右空白缩进").onClick(() => { + let margin = Number(this.leftMargin); + if (margin < 200) { + margin += halfleadingIndentation7; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + + Button("向左空白缩进").onClick(() => { + let margin = Number(this.leftMargin) + if (margin > 0) { + margin -= halfleadingIndentation7; + this.leftMargin = margin; + } + this.controller.updateParagraphStyle({ + start: -10, + end: -10, + style: { + leadingMargin: margin + } + }) + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder01.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder01.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe5074abe6c55bfe57ce7f2b4acede9c085b8def --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder01.ets @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb01placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder01 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb01placeholderBuilder2; + + @Builder + rmbplaceholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmbplaceholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmbplaceholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('80%') + } + + @Builder + rmbMyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmbplaceholderBuilder3() + }, { offset: this.my_offset }) + this.controller.addTextSpan("0123456789", + { + style: + { + fontColor: Color.Orange, + fontSize: 30 + } + }) + this.controller.addImageSpan($r("app.media.icon"), + { + imageStyle: + { + size: ["57px", "57px"] + } + }) + }) + .id('UiComponentTextRichEditorMenuBuilder01') + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmbMyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmbMyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmbMyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmbMyMenu(), RichEditorResponseType.DEFAULT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmbplaceholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmbplaceholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmbplaceholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder02.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder02.ets new file mode 100644 index 0000000000000000000000000000000000000000..f8b6414e13cb2e6520fb04c9f3dd3f6929bd8650 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder02.ets @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb02placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder02 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb02placeholderBuilder2; + + @Builder + rmb02placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb02placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb02placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb02placeholderBuilder3() + }, { offset: this.my_offset }) + this.controller.addTextSpan("0123456789", + { + style: + { + fontColor: Color.Orange, + fontSize: 30 + } + }) + this.controller.addImageSpan($r("app.media.icon"), + { + imageStyle: + { + size: ["57px", "57px"] + } + }) + }) + .id('UiComponentTextRichEditorMenuBuilder02') + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb02placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb02placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb02placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder03.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder03.ets new file mode 100644 index 0000000000000000000000000000000000000000..c5df1d5bce24b08a067cd6de453ef1f657ec7348 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder03.ets @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb03placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder03 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb03placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + }) + .id('UiComponentTextRichEditorMenuBuilder03') + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder04.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder04.ets new file mode 100644 index 0000000000000000000000000000000000000000..9728a2e89f29d9b0565aba79ffb0af674f1c48ba --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder04.ets @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb04placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder04 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb04placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + }) + .id('UiComponentTextRichEditorMenuBuilder04') + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder05.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder05.ets new file mode 100644 index 0000000000000000000000000000000000000000..fa2fd488420f6ddbd841bd5db681ae90b512ab87 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder05.ets @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb05placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder05 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb05placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + }) + .id('UiComponentTextRichEditorMenuBuilder05') + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder06.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder06.ets new file mode 100644 index 0000000000000000000000000000000000000000..150924e7284eaa210948ef9ad59c5534a77cdf25 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder06.ets @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb06placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder06 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb06placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + }) + .id('UiComponentTextRichEditorMenuBuilder06') + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder07.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder07.ets new file mode 100644 index 0000000000000000000000000000000000000000..13807adb713521e6c864d03f18dcc27a304bd143 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder07.ets @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb07placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder07 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb07placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + }) + .id('UiComponentTextRichEditorMenuBuilder07') + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder08.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder08.ets new file mode 100644 index 0000000000000000000000000000000000000000..983c96cbefaf9e4be4b1b65e079752027d47543c --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder08.ets @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb08placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder08 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb08placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + this.controller.addTextSpan("0123456789", + { + style: + { + fontColor: Color.Orange, + fontSize: 30 + } + }) + this.controller.addImageSpan($r("app.media.icon"), + { + imageStyle: + { + size: ["57px", "57px"] + } + }) + }) + .id('UiComponentTextRichEditorMenuBuilder08') + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder09.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder09.ets new file mode 100644 index 0000000000000000000000000000000000000000..7533f0798f34ea40b8fa52e555d529842dfec29e --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder09.ets @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb09placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder09 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb09placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + this.controller.addTextSpan("0123456789", + { + style: + { + fontColor: Color.Orange, + fontSize: 30 + } + }) + this.controller.addImageSpan($r("app.media.icon"), + { + imageStyle: + { + size: ["57px", "57px"] + } + }) + }) + .id('UiComponentTextRichEditorMenuBuilder09') + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder10.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder10.ets new file mode 100644 index 0000000000000000000000000000000000000000..00dd61310d1d28b3a65894aa67f1ab750919e9fb --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder10.ets @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb10placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder10 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb10placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + this.controller.addTextSpan("0123456789", + { + style: + { + fontColor: Color.Orange, + fontSize: 30 + } + }) + this.controller.addImageSpan($r("app.media.icon"), + { + imageStyle: + { + size: ["57px", "57px"] + } + }) + }) + .id('UiComponentTextRichEditorMenuBuilder10') + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.IMAGE, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file diff --git a/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder11.ets b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder11.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc203c371f8bcc79dc1415048ceb8eca1c226179 --- /dev/null +++ b/sample/ui_compare/uiCompareTest_02/entry/src/ohosTest/ets/testability/pages/UiComponentTextRichEditorMenuBuilder/UiComponentTextRichEditorMenuBuilder11.ets @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function rmb11placeholderBuilder2() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('okokokok').fontSize(10) + }.width('20%').height(50).padding(10).backgroundColor(Color.Red) +} + +@Entry +@Component +struct UiComponentTextRichEditorMenuBuilder11 { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + private start: number = 2; + private end: number = 4; + @State message: string = "[-1, -1]"; + @State content: string = ""; + private my_offset: number | undefined = undefined; + private my_builder: CustomBuilder = undefined; + @BuilderParam my_builder2:() => void = rmb11placeholderBuilder2; + + @Builder + rmb03placeholderBuilder() { + Row({ space: 2 }) { + Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) + Text('Custom Popup').fontSize(10) + }.width(100).height(50).padding(5) + } + + @Builder + rmb03placeholderBuilder3() { + Text("hello").padding('20').borderWidth(1).width('80%') + } + + @Builder + rmb03placeholderBuilder4() { + Column() { + Column({ space: 5 }) { + Text('direction:Row') + .fontSize(9) + .fontColor(0xCCCCCC) + .width('90%') + Flex({ direction: FlexDirection.Row }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.RowReverse }) { + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + Text('1').width('20%').height(50).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(50).backgroundColor(0xD2B48C) + } + .height(70) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.Column }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + + Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%') + Flex({ direction: FlexDirection.ColumnReverse }) { + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + Text('1').width('20%').height(40).backgroundColor(0xF5DEB3) + Text('1').width('20%').height(40).backgroundColor(0xD2B48C) + } + .height(160) + .width('90%') + .padding(10) + .backgroundColor(0xAFEEEE) + } + .width('90%') + .margin({ top: 5 }) + } + .width('60%') + } + + @Builder + rmb02MyMenu() { + Menu() { + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项1" }) + MenuItem({ startIcon: $r("app.media.icon"), content: "自定义菜单选项2" }) + .enabled(false) + } + } + + build() { + Column() { + Row() { + Button("获取选择内容 getSpans").onClick(() => { + console.info('getSpans='+JSON.stringify(this.controller.getSpans({ start:1, end:5 }))); + console.info('getParagraphs='+JSON.stringify(this.controller.getParagraphs({ start:1, end:5 }))); + this.content = ""; + this.controller.getSpans({ + start: this.start, + end: this.end + }).forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("获取选择内容 getSelection").onClick(() => { + this.content = ""; + let select = this.controller.getSelection(); + console.info("selection start " + select.selection[0] + " end " + select.selection[1]); + select.spans.forEach(item => { + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + this.content += (item as RichEditorTextSpanResult).value; + this.content += "\n"; + console.info("text span: " + (item as RichEditorTextSpanResult).value); + } + }) + }) + Button("删除选择内容").onClick(() => { + this.controller.deleteSpans({ + start: this.start, + end: this.end + }) + }) + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("10%") + + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan( + () => { + this.rmb03placeholderBuilder3() + }, { offset: this.my_offset }) + this.controller.addTextSpan("0123456789", + { + style: + { + fontColor: Color.Orange, + fontSize: 30 + } + }) + this.controller.addImageSpan($r("app.media.icon"), + { + imageStyle: + { + size: ["57px", "57px"] + } + }) + }) + .id('UiComponentTextRichEditorMenuBuilder11') + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.BUILDER, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.LONG_PRESS) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.RIGHT_CLICK) + .bindSelectionMenu(RichEditorSpanType.MIXED, this.rmb02MyMenu(), RichEditorResponseType.SELECT) + .onSelect((value: RichEditorSelection) => { + this.start = value.selection[0]; + this.end = value.selection[1]; + this.message = "[" + this.start + ", " + this.end + "]"; + console.info("onSelect="+JSON.stringify(value)); + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + console.info("---------------------- aboutToIMEInput --------------------"); + console.info("aboutToIMEInput="+JSON.stringify(value)); + console.info("insertOffset:" + value.insertOffset); + console.info("insertValue:" + value.insertValue); + return true; + }) + .onIMEInputComplete((value: RichEditorTextSpanResult) => { + console.info("---------------------- onIMEInputComplete --------------------"); + console.info("onIMEInputComplete="+JSON.stringify(value)); + console.info("spanIndex:" + value.spanPosition.spanIndex); + console.info("spanRange:[" + value.spanPosition.spanRange[0] + "," + value.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + value.offsetInSpan[0] + "," + value.offsetInSpan[1] + "]"); + console.info("value:" + value.value); + }) + .aboutToDelete((value: RichEditorDeleteValue) => { + value.richEditorDeleteSpans.forEach(item => { + console.info("---------------------- item --------------------"); + console.info("spanIndex=" + item.spanPosition.spanIndex); + console.info("spanRange:[" + item.spanPosition.spanRange[0] + "," + item.spanPosition.spanRange[1] + "]"); + console.info("offsetInSpan:[" + item.offsetInSpan[0] + "," + item.offsetInSpan[1] + "]"); + if (typeof (item as RichEditorImageSpanResult)['imageStyle'] != 'undefined') { + if ((item as RichEditorImageSpanResult).valueResourceStr == "") { + console.info("builder span index " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range : " + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + (item as RichEditorImageSpanResult).imageStyle[0] + ", " + (item as RichEditorImageSpanResult).imageStyle[1]) + } else { + console.info("image span " + (item as RichEditorImageSpanResult).valueResourceStr + ", index : " + (item as RichEditorImageSpanResult).spanPosition.spanIndex + ", range: " + + (item as RichEditorImageSpanResult).offsetInSpan[0] + ", " + (item as RichEditorImageSpanResult).offsetInSpan[1] + ", size : " + + (item as RichEditorImageSpanResult).imageStyle.size[0] + ", " + (item as RichEditorImageSpanResult).imageStyle.size[1]) + } + } else { + console.info("delete text: " + (item as RichEditorTextSpanResult).value); + } + }) + return true; + }) + .borderWidth(1) + .borderColor(Color.Green) + .width("100%") + .height("20%") + + Button("add span") + .onClick(() => { + let num = this.controller.addBuilderSpan(this.my_builder, { offset: this.my_offset }); + console.info('addBuilderSpan return ' + num); + }) + Button("add image") + .onClick(() => { + let num = this.controller.addImageSpan($r("app.media.icon"), { + imageStyle: { + size: ["50px", "50px"], + verticalAlign: ImageSpanAlignment.BOTTOM, + layoutStyle: { + borderRadius: undefined, + margin: undefined + } + } + }) + console.info('addImageSpan return' + num); + }) + Row() { + Button('builder1').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder() + }; + }) + Button('builder2').onClick(() => { + this.my_builder = () => { + this.my_builder2() + }; + }) + Button('builder3').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder3() + }; + }) + Button('builder4').onClick(() => { + this.my_builder = () => { + this.rmb03placeholderBuilder4() + }; + }) + } + } + .borderWidth(1) + .borderColor(Color.Red) + .width("100%") + .height("70%") + } + } +} \ No newline at end of file