mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-12-03 21:13:45 +00:00
editabletitlebar selecttitlebar tabtitlebar 适老化
Signed-off-by: zhaobinbin <zhaobinbin8@h-partners.com>
This commit is contained in:
parent
4f06aa4b88
commit
69cf21166f
@ -674,6 +674,9 @@ class ImageMenuItem extends ViewPU {
|
||||
this.minFontSize = 1.75;
|
||||
this.maxFontSize = 3.2;
|
||||
this.longPressTime = 500;
|
||||
this.isFollowingSystemFontScale = false;
|
||||
this.maxFontScale = 1;
|
||||
this.systemFontScale = 1;
|
||||
this.__fontSize = new SynchedPropertySimpleOneWayPU(e4.fontSize, this, 'fontSize');
|
||||
this.__isOnFocus = new ObservedPropertySimplePU(false, this, 'isOnFocus');
|
||||
this.__isOnHover = new ObservedPropertySimplePU(false, this, 'isOnHover');
|
||||
@ -731,6 +734,15 @@ class ImageMenuItem extends ViewPU {
|
||||
if (c4.longPressTime !== undefined) {
|
||||
this.longPressTime = c4.longPressTime;
|
||||
}
|
||||
if (c4.isFollowingSystemFontScale !== undefined) {
|
||||
this.isFollowingSystemFontScale = c4.isFollowingSystemFontScale;
|
||||
}
|
||||
if (c4.maxFontScale !== undefined) {
|
||||
this.maxFontScale = c4.maxFontScale;
|
||||
}
|
||||
if (c4.systemFontScale !== undefined) {
|
||||
this.systemFontScale = c4.systemFontScale;
|
||||
}
|
||||
if (c4.fontSize === undefined) {
|
||||
this.__fontSize.set(1);
|
||||
}
|
||||
@ -841,6 +853,27 @@ class ImageMenuItem extends ViewPU {
|
||||
this.isOnClick = false;
|
||||
}
|
||||
}
|
||||
aboutToAppear() {
|
||||
let h = this.getUIContext();
|
||||
this.isFollowingSystemFontScale = h.isFollowingSystemFontScale();
|
||||
this.maxFontScale = h.getMaxFontScale();
|
||||
}
|
||||
decideFontScale() {
|
||||
try {
|
||||
let k2 = this.getUIContext();
|
||||
this.systemFontScale = k2.getHostContext()?.config.fontSizeScale ?? 1;
|
||||
if (!this.isFollowingSystemFontScale) {
|
||||
return 1;
|
||||
}
|
||||
return Math.min(this.systemFontScale, this.maxFontScale);
|
||||
}
|
||||
catch (h2) {
|
||||
let i2 = h2.code;
|
||||
let j2 = h2.message;
|
||||
hilog.error(0x3900, 'Ace', `Faild to decideFontScale,cause, code: ${i2}, message: ${j2}`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
getBgColor() {
|
||||
if (this.isOnClick) {
|
||||
return this.editableTitleBarTheme.iconBackgroundPressedColor;
|
||||
@ -950,8 +983,7 @@ class ImageMenuItem extends ViewPU {
|
||||
Gesture.create(GesturePriority.Low);
|
||||
LongPressGesture.create({ repeat: false, duration: this.longPressTime });
|
||||
LongPressGesture.onAction((l3) => {
|
||||
let m3 = this.getUIContext().getHostContext();
|
||||
this.fontSize = m3.config?.fontSizeScale ?? 1;
|
||||
this.fontSize = this.decideFontScale();
|
||||
if (l3) {
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.open();
|
||||
@ -1054,8 +1086,7 @@ class ImageMenuItem extends ViewPU {
|
||||
Gesture.create(GesturePriority.Low);
|
||||
LongPressGesture.create({ repeat: false, duration: this.longPressTime });
|
||||
LongPressGesture.onAction((o2) => {
|
||||
let p2 = this.getUIContext().getHostContext();
|
||||
this.fontSize = p2.config?.fontSizeScale ?? 1;
|
||||
this.fontSize = this.decideFontScale();
|
||||
if (o2) {
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.open();
|
||||
|
@ -344,6 +344,10 @@ struct ImageMenuItem {
|
||||
minFontSize: number = 1.75;
|
||||
maxFontSize: number = 3.2;
|
||||
longPressTime: number = 500;
|
||||
isFollowingSystemFontScale: boolean = false;
|
||||
maxFontScale: number = 1;
|
||||
systemFontScale?: number = 1;
|
||||
|
||||
@Prop fontSize: number = 1;
|
||||
@State isOnFocus: boolean = false;
|
||||
@State isOnHover: boolean = false;
|
||||
@ -433,6 +437,28 @@ struct ImageMenuItem {
|
||||
}
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale();
|
||||
this.maxFontScale = uiContent.getMaxFontScale();
|
||||
}
|
||||
|
||||
decideFontScale(): number {
|
||||
try {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config.fontSizeScale ?? 1;
|
||||
if (!this.isFollowingSystemFontScale) {
|
||||
return 1;
|
||||
}
|
||||
return Math.min(this.systemFontScale, this.maxFontScale);
|
||||
} catch (exception) {
|
||||
let code: number = (exception as BusinessError).code;
|
||||
let message: string = (exception as BusinessError).message;
|
||||
hilog.error(0x3900, 'Ace', `Faild to decideFontScale,cause, code: ${code}, message: ${message}`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Styles
|
||||
buttonEventStyle() {
|
||||
.onFocus(() => {
|
||||
@ -460,8 +486,7 @@ struct ImageMenuItem {
|
||||
.gesture(
|
||||
LongPressGesture({ repeat: false, duration: this.longPressTime })
|
||||
.onAction((event: GestureEvent) => {
|
||||
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
|
||||
this.fontSize = context.config?.fontSizeScale ?? 1;
|
||||
this.fontSize = this.decideFontScale();
|
||||
if (event) {
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.open()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,17 +14,28 @@
|
||||
*/
|
||||
|
||||
import { KeyCode } from '@ohos.multimodalInput.keyCode'
|
||||
import window from '@ohos.window'
|
||||
import common from '@ohos.app.ability.common'
|
||||
import { BusinessError } from '@kit.BasicServicesKit'
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit'
|
||||
|
||||
export declare class SelectTitleBarMenuItem {
|
||||
public value: ResourceStr;
|
||||
public isEnabled?: boolean;
|
||||
public action?: () => void;
|
||||
export interface SelectTitleBarMenuItem {
|
||||
value: ResourceStr;
|
||||
isEnabled?: boolean;
|
||||
action?: () => void;
|
||||
label?: ResourceStr;
|
||||
}
|
||||
|
||||
const PUBLIC_MORE: Resource = $r('sys.media.ohos_ic_public_more');
|
||||
|
||||
const PUBLIC_BACK: Resource = $r('sys.media.ohos_ic_back');
|
||||
|
||||
const TEXT_EDITABLE_DIALOG = '18.3fp'
|
||||
const IMAGE_SIZE = '64vp'
|
||||
const MAX_DIALOG = '256vp'
|
||||
const MIN_DIALOG = '216vp'
|
||||
|
||||
|
||||
@Component
|
||||
export struct SelectTitleBar {
|
||||
@State selected: number = 0
|
||||
@ -49,6 +60,7 @@ export struct SelectTitleBar {
|
||||
|
||||
@State selectMaxWidth: number = 0;
|
||||
@State backActive: boolean = false;
|
||||
@State fontSize: number = 1;
|
||||
|
||||
build() {
|
||||
Flex({
|
||||
@ -167,7 +179,16 @@ export struct SelectTitleBar {
|
||||
@Component
|
||||
struct CollapsibleMenuSection {
|
||||
menuItems: Array<SelectTitleBarMenuItem> = [];
|
||||
item: SelectTitleBarMenuItem = {
|
||||
value: PUBLIC_MORE,
|
||||
label: $r('sys.string.ohos_toolbar_more'),
|
||||
} as SelectTitleBarMenuItem;
|
||||
index: number = 0;
|
||||
longPressTime: number = 500;
|
||||
minFontSize: number = 1.75;
|
||||
isFollowingSystemFontScale: boolean = false;
|
||||
maxFontScale: number = 1;
|
||||
systemFontScale?: number = 1;
|
||||
|
||||
static readonly maxCountOfVisibleItems = 3
|
||||
private static readonly focusPadding = 4
|
||||
@ -179,6 +200,22 @@ struct CollapsibleMenuSection {
|
||||
@State isMoreIconOnFocus: boolean = false
|
||||
@State isMoreIconOnHover: boolean = false
|
||||
@State isMoreIconOnClick: boolean = false
|
||||
@State fontSize: number = 1
|
||||
|
||||
dialogController: CustomDialogController | null = new CustomDialogController({
|
||||
builder: SelectTitleBarDialog({
|
||||
cancel: () => {
|
||||
},
|
||||
confirm: () => {
|
||||
},
|
||||
SelectTitleDialog: this.item,
|
||||
SelectTitleBarDialog: this.item.label ? this.item.label : '',
|
||||
fontSize: this.fontSize,
|
||||
}),
|
||||
maskColor: Color.Transparent,
|
||||
isModal: true,
|
||||
customStyle: true,
|
||||
})
|
||||
|
||||
getMoreIconFgColor() {
|
||||
return this.isMoreIconOnClick
|
||||
@ -197,6 +234,9 @@ struct CollapsibleMenuSection {
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale();
|
||||
this.maxFontScale = uiContent.getMaxFontScale();
|
||||
this.menuItems.forEach((item, index) => {
|
||||
if (item.isEnabled && this.firstFocusableIndex == -1 &&
|
||||
index > CollapsibleMenuSection.maxCountOfVisibleItems - 2) {
|
||||
@ -205,6 +245,22 @@ struct CollapsibleMenuSection {
|
||||
})
|
||||
}
|
||||
|
||||
decideFontScale(): number {
|
||||
try {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config.fontSizeScale ?? 1;
|
||||
if (!this.isFollowingSystemFontScale) {
|
||||
return 1;
|
||||
}
|
||||
return Math.min(this.systemFontScale, this.maxFontScale);
|
||||
} catch (exception) {
|
||||
let code: number = (exception as BusinessError).code;
|
||||
let message: string = (exception as BusinessError).message;
|
||||
hilog.error(0x3900, 'Ace', `Faild to decideFontScale,cause, code: ${code}, message: ${message}`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
@ -223,6 +279,7 @@ struct CollapsibleMenuSection {
|
||||
.width(ImageMenuItem.imageSize)
|
||||
.height(ImageMenuItem.imageSize)
|
||||
.focusable(true)
|
||||
.draggable(false)
|
||||
.fillColor($r('sys.color.icon_primary'))
|
||||
}
|
||||
.width(ImageMenuItem.imageHotZoneWidth)
|
||||
@ -265,11 +322,24 @@ struct CollapsibleMenuSection {
|
||||
if (event.type === TouchType.Down) {
|
||||
this.isMoreIconOnClick = true
|
||||
}
|
||||
if (event.type === TouchType.Up) {
|
||||
if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
|
||||
this.isMoreIconOnClick = false
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
.onClick(() => this.isPopupShown = true)
|
||||
.gesture(
|
||||
LongPressGesture({ repeat: false, duration: this.longPressTime })
|
||||
.onAction((event: GestureEvent) => {
|
||||
this.fontSize = this.decideFontScale();
|
||||
if (event) {
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.open()
|
||||
}
|
||||
}
|
||||
}))
|
||||
.bindPopup(this.isPopupShown, {
|
||||
builder: this.popupBuilder,
|
||||
placement: Placement.Bottom,
|
||||
@ -295,8 +365,8 @@ struct CollapsibleMenuSection {
|
||||
Column() {
|
||||
ForEach(this.menuItems.slice(CollapsibleMenuSection.maxCountOfVisibleItems - 1, this.menuItems.length),
|
||||
(item: SelectTitleBarMenuItem, index) => {
|
||||
ImageMenuItem({ item: item, index: this.index * 1000 + CollapsibleMenuSection.maxCountOfVisibleItems + index })
|
||||
})
|
||||
ImageMenuItem({ item: item, index: this.index * 1000 + CollapsibleMenuSection.maxCountOfVisibleItems + index })
|
||||
})
|
||||
}
|
||||
.width(ImageMenuItem.imageHotZoneWidth + CollapsibleMenuSection.focusPadding * CollapsibleMenuSection.marginsNum)
|
||||
.margin({ top: CollapsibleMenuSection.focusPadding, bottom: CollapsibleMenuSection.focusPadding })
|
||||
@ -310,6 +380,11 @@ struct CollapsibleMenuSection {
|
||||
struct ImageMenuItem {
|
||||
item: SelectTitleBarMenuItem = {} as SelectTitleBarMenuItem;
|
||||
index: number = 0;
|
||||
longPressTime: number = 500;
|
||||
minFontSize: number = 1.75;
|
||||
isFollowingSystemFontScale: boolean = false;
|
||||
maxFontScale: number = 1;
|
||||
systemFontScale?: number = 1;
|
||||
|
||||
static readonly imageSize = 24
|
||||
static readonly imageHotZoneWidth = 48
|
||||
@ -321,6 +396,32 @@ struct ImageMenuItem {
|
||||
@State isOnFocus: boolean = false
|
||||
@State isOnHover: boolean = false
|
||||
@State isOnClick: boolean = false
|
||||
@Prop fontSize: number = 1
|
||||
|
||||
dialogController: CustomDialogController | null = new CustomDialogController({
|
||||
builder: SelectTitleBarDialog({
|
||||
cancel: () => {
|
||||
},
|
||||
confirm: () => {
|
||||
},
|
||||
SelectTitleDialog: this.item,
|
||||
SelectTitleBarDialog: this.item.label ? this.item.label : this.textDialog(),
|
||||
fontSize: this.fontSize,
|
||||
}),
|
||||
maskColor: Color.Transparent,
|
||||
isModal: true,
|
||||
customStyle: true,
|
||||
})
|
||||
|
||||
private textDialog(): ResourceStr {
|
||||
if (this.item.value === PUBLIC_MORE) {
|
||||
return $r('sys.string.ohos_toolbar_more');
|
||||
} else if (this.item.value === PUBLIC_BACK) {
|
||||
return $r('sys.string.icon_back');
|
||||
} else {
|
||||
return this.item.label ? this.item.label : '';
|
||||
}
|
||||
}
|
||||
|
||||
getFgColor() {
|
||||
return this.isOnClick
|
||||
@ -338,9 +439,32 @@ struct ImageMenuItem {
|
||||
}
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale();
|
||||
this.maxFontScale = uiContent.getMaxFontScale();
|
||||
}
|
||||
|
||||
decideFontScale(): number {
|
||||
try {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config.fontSizeScale ?? 1;
|
||||
if (!this.isFollowingSystemFontScale) {
|
||||
return 1;
|
||||
}
|
||||
return Math.min(this.systemFontScale, this.maxFontScale);
|
||||
} catch (exception) {
|
||||
let code: number = (exception as BusinessError).code;
|
||||
let message: string = (exception as BusinessError).message;
|
||||
hilog.error(0x3900, 'Ace', `Faild to decideFontScale,cause, code: ${code}, message: ${message}`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Image(this.item.value)
|
||||
.draggable(false)
|
||||
.width(ImageMenuItem.imageSize)
|
||||
.height(ImageMenuItem.imageSize)
|
||||
.focusable(this.item.isEnabled)
|
||||
@ -404,10 +528,108 @@ struct ImageMenuItem {
|
||||
if (event.type === TouchType.Down) {
|
||||
this.isOnClick = true
|
||||
}
|
||||
if (event.type === TouchType.Up) {
|
||||
if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
|
||||
this.isOnClick = false
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
.onClick(() => this.item.isEnabled && this.item.action && this.item.action())
|
||||
.gesture(
|
||||
LongPressGesture({ repeat: false, duration: this.longPressTime })
|
||||
.onAction((event: GestureEvent) => {
|
||||
this.fontSize = this.decideFontScale();
|
||||
if (event) {
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.open()
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SelectTitleBarDialog
|
||||
*/
|
||||
@CustomDialog
|
||||
struct SelectTitleBarDialog {
|
||||
SelectTitleDialog: SelectTitleBarMenuItem = {} as SelectTitleBarMenuItem;
|
||||
callbackId: number | undefined = undefined;
|
||||
SelectTitleBarDialog?: ResourceStr = '';
|
||||
mainWindowStage: window.Window | undefined = undefined;
|
||||
controller?: CustomDialogController
|
||||
minFontSize: number = 1.75;
|
||||
maxFontSize: number = 3.2;
|
||||
screenWidth: number = 640;
|
||||
verticalScreenLines: number = 6;
|
||||
horizontalsScreenLines: number = 1;
|
||||
@StorageLink('mainWindow') mainWindow: Promise<window.Window> | undefined = undefined;
|
||||
@State fontSize: number = 1;
|
||||
@State maxLines: number = 1;
|
||||
@StorageProp('windowStandardHeight') windowStandardHeight: number = 0;
|
||||
cancel: () => void = () => {
|
||||
}
|
||||
confirm: () => void = () => {
|
||||
}
|
||||
|
||||
build() {
|
||||
if (this.SelectTitleBarDialog) {
|
||||
Column() {
|
||||
Image(this.SelectTitleDialog.value)
|
||||
.width(IMAGE_SIZE)
|
||||
.height(IMAGE_SIZE)
|
||||
.margin({
|
||||
top: $r('sys.float.padding_level24'),
|
||||
bottom: $r('sys.float.padding_level8'),
|
||||
})
|
||||
.fillColor($r('sys.color.icon_primary'))
|
||||
Column() {
|
||||
Text(this.SelectTitleBarDialog)
|
||||
.fontSize(TEXT_EDITABLE_DIALOG)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.maxLines(this.maxLines)
|
||||
.width('100%')
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('sys.color.font_primary'))
|
||||
}
|
||||
.width('100%')
|
||||
.padding({
|
||||
left: $r('sys.float.padding_level4'),
|
||||
right: $r('sys.float.padding_level4'),
|
||||
bottom: $r('sys.float.padding_level12'),
|
||||
})
|
||||
}
|
||||
.width(this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG)
|
||||
.constraintSize({ minHeight: this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG })
|
||||
.backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK)
|
||||
.shadow(ShadowStyle.OUTER_DEFAULT_LG)
|
||||
.borderRadius($r('sys.float.corner_radius_level10'))
|
||||
} else {
|
||||
Column() {
|
||||
Image(this.SelectTitleDialog.value)
|
||||
.width(IMAGE_SIZE)
|
||||
.height(IMAGE_SIZE)
|
||||
.fillColor($r('sys.color.icon_primary'))
|
||||
}
|
||||
.width(this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG)
|
||||
.constraintSize({ minHeight: this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG })
|
||||
.backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK)
|
||||
.shadow(ShadowStyle.OUTER_DEFAULT_LG)
|
||||
.borderRadius($r('sys.float.corner_radius_level10'))
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
}
|
||||
|
||||
async aboutToAppear(): Promise<void> {
|
||||
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
|
||||
this.mainWindowStage = context.windowStage.getMainWindowSync();
|
||||
let properties: window.WindowProperties = this.mainWindowStage.getWindowProperties();
|
||||
let rect = properties.windowRect;
|
||||
if (px2vp(rect.height) > this.screenWidth) {
|
||||
this.maxLines = this.verticalScreenLines;
|
||||
} else {
|
||||
this.maxLines = this.horizontalsScreenLines;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -15,11 +15,16 @@
|
||||
|
||||
import { KeyCode } from '@ohos.multimodalInput.keyCode'
|
||||
import MeasureText from '@ohos.measure'
|
||||
import window from '@ohos.window'
|
||||
import common from '@ohos.app.ability.common'
|
||||
import { BusinessError } from '@kit.BasicServicesKit'
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit'
|
||||
|
||||
export interface TabTitleBarMenuItem {
|
||||
value: ResourceStr;
|
||||
isEnabled?: boolean;
|
||||
action?: () => void;
|
||||
label?: ResourceStr;
|
||||
}
|
||||
|
||||
export interface TabTitleBarTabItem {
|
||||
@ -28,6 +33,10 @@ export interface TabTitleBarTabItem {
|
||||
}
|
||||
|
||||
const PUBLIC_MORE = $r('sys.media.ohos_ic_public_more')
|
||||
const TEXT_EDITABLE_DIALOG = '18.3fp'
|
||||
const IMAGE_SIZE = '64vp'
|
||||
const MAX_DIALOG = '256vp'
|
||||
const MIN_DIALOG = '216vp'
|
||||
|
||||
@Component
|
||||
export struct TabTitleBar {
|
||||
@ -37,6 +46,7 @@ export struct TabTitleBar {
|
||||
|
||||
@State tabWidth: number = 0
|
||||
@State currentIndex: number = 0
|
||||
@State fontSize: number = 1
|
||||
|
||||
static readonly totalHeight = 56
|
||||
static readonly correctionOffset = -40.0
|
||||
@ -194,6 +204,15 @@ export struct TabTitleBar {
|
||||
struct CollapsibleMenuSection {
|
||||
menuItems: Array<TabTitleBarMenuItem> = [];
|
||||
index: number = 0;
|
||||
item: TabTitleBarMenuItem = {
|
||||
value: PUBLIC_MORE,
|
||||
label: $r('sys.string.ohos_toolbar_more'),
|
||||
} as TabTitleBarMenuItem;
|
||||
longPressTime: number = 500;
|
||||
minFontSize: number = 1.75;
|
||||
isFollowingSystemFontScale: boolean = false;
|
||||
maxFontScale: number = 1;
|
||||
systemFontScale?: number = 1;
|
||||
|
||||
static readonly maxCountOfVisibleItems = 1
|
||||
private static readonly focusPadding = 4
|
||||
@ -205,6 +224,22 @@ struct CollapsibleMenuSection {
|
||||
@State isMoreIconOnFocus: boolean = false
|
||||
@State isMoreIconOnHover: boolean = false
|
||||
@State isMoreIconOnClick: boolean = false
|
||||
@Prop fontSize: number = 1
|
||||
|
||||
dialogController: CustomDialogController | null = new CustomDialogController({
|
||||
builder: TabTitleBarDialog({
|
||||
cancel: () => {
|
||||
},
|
||||
confirm: () => {
|
||||
},
|
||||
TabTitleDialog: this.item,
|
||||
TabTitleBarDialog: this.item.label ? this.item.label : '',
|
||||
fontSize: this.fontSize,
|
||||
}),
|
||||
maskColor: Color.Transparent,
|
||||
isModal: true,
|
||||
customStyle: true,
|
||||
})
|
||||
|
||||
getMoreIconFgColor() {
|
||||
return this.isMoreIconOnClick
|
||||
@ -223,6 +258,9 @@ struct CollapsibleMenuSection {
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale();
|
||||
this.maxFontScale = uiContent.getMaxFontScale();
|
||||
this.menuItems.forEach((item, index) => {
|
||||
if (item.isEnabled && this.firstFocusableIndex == -1 &&
|
||||
index > CollapsibleMenuSection.maxCountOfVisibleItems - 2) {
|
||||
@ -231,6 +269,22 @@ struct CollapsibleMenuSection {
|
||||
})
|
||||
}
|
||||
|
||||
decideFontScale(): number {
|
||||
try {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config.fontSizeScale ?? 1;
|
||||
if (!this.isFollowingSystemFontScale) {
|
||||
return 1;
|
||||
}
|
||||
return Math.min(this.systemFontScale, this.maxFontScale);
|
||||
} catch (exception) {
|
||||
let code: number = (exception as BusinessError).code;
|
||||
let message: string = (exception as BusinessError).message;
|
||||
hilog.error(0x3900, 'Ace', `Faild to decideFontScale,cause, code: ${code}, message: ${message}`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
@ -249,6 +303,7 @@ struct CollapsibleMenuSection {
|
||||
.width(ImageMenuItem.imageSize)
|
||||
.height(ImageMenuItem.imageSize)
|
||||
.focusable(true)
|
||||
.draggable(false)
|
||||
.fillColor($r('sys.color.icon_primary'))
|
||||
}
|
||||
.width(ImageMenuItem.imageHotZoneWidth)
|
||||
@ -291,11 +346,24 @@ struct CollapsibleMenuSection {
|
||||
if (event.type === TouchType.Down) {
|
||||
this.isMoreIconOnClick = true
|
||||
}
|
||||
if (event.type === TouchType.Up) {
|
||||
if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
|
||||
this.isMoreIconOnClick = false
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
.onClick(() => this.isPopupShown = true)
|
||||
.gesture(
|
||||
LongPressGesture({ repeat: false, duration: this.longPressTime })
|
||||
.onAction((event: GestureEvent) => {
|
||||
this.fontSize = this.decideFontScale();
|
||||
if (event) {
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.open()
|
||||
}
|
||||
}
|
||||
}))
|
||||
.bindPopup(this.isPopupShown, {
|
||||
builder: this.popupBuilder,
|
||||
placement: Placement.Bottom,
|
||||
@ -334,12 +402,19 @@ struct CollapsibleMenuSection {
|
||||
@Component
|
||||
struct TabContentItem {
|
||||
item: TabTitleBarTabItem = { title: '' };
|
||||
TabItem: TabTitleBarMenuItem = {} as TabTitleBarMenuItem
|
||||
index: number = 0;
|
||||
maxIndex: number = 0;
|
||||
onCustomClick?: (index: number) => void
|
||||
onImageComplete?: (width: number) => void
|
||||
longPressTime: number = 500
|
||||
minFontSize: number = 1.75
|
||||
isFollowingSystemFontScale: boolean = false;
|
||||
maxFontScale: number = 1;
|
||||
systemFontScale?: number = 1;
|
||||
|
||||
@Prop currentIndex: number
|
||||
@Prop fontSize: number = 1
|
||||
|
||||
@State isOnFocus: boolean = false
|
||||
@State isOnHover: boolean = false
|
||||
@ -358,6 +433,31 @@ struct TabContentItem {
|
||||
static readonly paddingRight = 8
|
||||
static readonly marginFirst = 16
|
||||
|
||||
private ToTabItem(item: TabTitleBarTabItem): TabTitleBarMenuItem {
|
||||
if (item.title) {
|
||||
this.TabItem.label = item.title;
|
||||
}
|
||||
if (item.icon) {
|
||||
this.TabItem.value = item.icon;
|
||||
}
|
||||
return this.TabItem;
|
||||
}
|
||||
|
||||
dialogController: CustomDialogController | null = new CustomDialogController({
|
||||
builder: TabTitleBarDialog({
|
||||
cancel: () => {
|
||||
},
|
||||
confirm: () => {
|
||||
},
|
||||
TabTitleDialog: this.ToTabItem(this.item),
|
||||
TabTitleBarDialog: this.ToTabItem(this.item).label ? this.ToTabItem(this.item).label : '',
|
||||
fontSize: this.fontSize,
|
||||
}),
|
||||
maskColor: Color.Transparent,
|
||||
isModal: true,
|
||||
customStyle: true,
|
||||
})
|
||||
|
||||
getBgColor() {
|
||||
if (this.isOnClick) {
|
||||
return $r('sys.color.ohos_id_color_click_effect')
|
||||
@ -388,6 +488,28 @@ struct TabContentItem {
|
||||
return TabContentItem.imageSize / Math.max(this.imageHeight, 1.0) * this.imageWidth
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale();
|
||||
this.maxFontScale = uiContent.getMaxFontScale();
|
||||
}
|
||||
|
||||
decideFontScale(): number {
|
||||
try {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config.fontSizeScale ?? 1;
|
||||
if (!this.isFollowingSystemFontScale) {
|
||||
return 1;
|
||||
}
|
||||
return Math.min(this.systemFontScale, this.maxFontScale);
|
||||
} catch (exception) {
|
||||
let code: number = (exception as BusinessError).code;
|
||||
let message: string = (exception as BusinessError).message;
|
||||
hilog.error(0x3900, 'Ace', `Faild to decideFontScale,cause, code: ${code}, message: ${message}`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Stack() {
|
||||
Row() {
|
||||
@ -439,6 +561,7 @@ struct TabContentItem {
|
||||
.width(this.getImageLayoutWidth())
|
||||
.height(TabContentItem.imageSize)
|
||||
.objectFit(ImageFit.Fill)
|
||||
.draggable(false)
|
||||
.scale({
|
||||
x: this.getImageScaleFactor(),
|
||||
y: this.getImageScaleFactor()
|
||||
@ -489,11 +612,24 @@ struct TabContentItem {
|
||||
if (event.type === TouchType.Down) {
|
||||
this.isOnClick = true
|
||||
}
|
||||
if (event.type === TouchType.Up) {
|
||||
if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
|
||||
this.isOnClick = false
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
.onClick(() => this.onCustomClick && this.onCustomClick(this.index))
|
||||
.gesture(
|
||||
LongPressGesture({ repeat: false, duration: this.longPressTime })
|
||||
.onAction((event: GestureEvent) => {
|
||||
this.fontSize = this.decideFontScale();
|
||||
if (event) {
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.open()
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
.justifyContent(FlexAlign.Center)
|
||||
@ -537,6 +673,11 @@ struct TabContentItem {
|
||||
struct ImageMenuItem {
|
||||
item: TabTitleBarMenuItem = { value: '' };
|
||||
index: number = 0;
|
||||
longPressTime: number = 500;
|
||||
minFontSize: number = 1.75;
|
||||
isFollowingSystemFontScale: boolean = false;
|
||||
maxFontScale: number = 1;
|
||||
systemFontScale?: number = 1;
|
||||
|
||||
static readonly imageSize = 24
|
||||
static readonly imageHotZoneWidth = 48
|
||||
@ -545,10 +686,34 @@ struct ImageMenuItem {
|
||||
static readonly disabledImageOpacity = 0.4
|
||||
static readonly focusablePrefix = "Id-TabTitleBar-ImageMenuItem-"
|
||||
|
||||
@Prop fontSize: number = 1;
|
||||
@State isOnFocus: boolean = false
|
||||
@State isOnHover: boolean = false
|
||||
@State isOnClick: boolean = false
|
||||
|
||||
dialogController: CustomDialogController | null = new CustomDialogController({
|
||||
builder: TabTitleBarDialog({
|
||||
cancel: () => {
|
||||
},
|
||||
confirm: () => {
|
||||
},
|
||||
TabTitleDialog: this.item,
|
||||
TabTitleBarDialog: this.item.label ? this.item.label : this.textDialog(),
|
||||
fontSize: this.fontSize,
|
||||
}),
|
||||
maskColor: Color.Transparent,
|
||||
isModal: true,
|
||||
customStyle: true,
|
||||
})
|
||||
|
||||
private textDialog(): ResourceStr {
|
||||
if (this.item.value === PUBLIC_MORE) {
|
||||
return $r('sys.string.ohos_toolbar_more');
|
||||
} else {
|
||||
return this.item.label ? this.item.label : '';
|
||||
}
|
||||
}
|
||||
|
||||
getFgColor() {
|
||||
return this.isOnClick
|
||||
? $r('sys.color.ohos_id_color_titlebar_icon_pressed')
|
||||
@ -565,6 +730,28 @@ struct ImageMenuItem {
|
||||
}
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale();
|
||||
this.maxFontScale = uiContent.getMaxFontScale();
|
||||
}
|
||||
|
||||
decideFontScale(): number {
|
||||
try {
|
||||
let uiContent: UIContext = this.getUIContext();
|
||||
this.systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config.fontSizeScale ?? 1;
|
||||
if (!this.isFollowingSystemFontScale) {
|
||||
return 1;
|
||||
}
|
||||
return Math.min(this.systemFontScale, this.maxFontScale);
|
||||
} catch (exception) {
|
||||
let code: number = (exception as BusinessError).code;
|
||||
let message: string = (exception as BusinessError).message;
|
||||
hilog.error(0x3900, 'Ace', `Faild to decideFontScale,cause, code: ${code}, message: ${message}`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Image(this.item.value)
|
||||
@ -572,6 +759,7 @@ struct ImageMenuItem {
|
||||
.height(ImageMenuItem.imageSize)
|
||||
.focusable(this.item.isEnabled)
|
||||
.key(ImageMenuItem.focusablePrefix + this.index)
|
||||
.draggable(false)
|
||||
}
|
||||
.width(ImageMenuItem.imageHotZoneWidth)
|
||||
.height(ImageMenuItem.imageHotZoneWidth)
|
||||
@ -630,10 +818,108 @@ struct ImageMenuItem {
|
||||
if (event.type === TouchType.Down) {
|
||||
this.isOnClick = true
|
||||
}
|
||||
if (event.type === TouchType.Up) {
|
||||
if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
|
||||
this.isOnClick = false
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
.onClick(() => this.item.isEnabled && this.item.action && this.item.action())
|
||||
.gesture(
|
||||
LongPressGesture({ repeat: false, duration: this.longPressTime })
|
||||
.onAction((event: GestureEvent) => {
|
||||
this.fontSize = this.decideFontScale();
|
||||
if (event) {
|
||||
if (this.fontSize >= this.minFontSize) {
|
||||
this.dialogController?.open()
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TabTitleBarDialog
|
||||
*/
|
||||
@CustomDialog
|
||||
struct TabTitleBarDialog {
|
||||
TabTitleDialog: TabTitleBarMenuItem = { value: '' };
|
||||
callbackId: number | undefined = undefined;
|
||||
TabTitleBarDialog?: ResourceStr = '';
|
||||
mainWindowStage: window.Window | undefined = undefined;
|
||||
controller?: CustomDialogController
|
||||
minFontSize: number = 1.75;
|
||||
maxFontSize: number = 3.2;
|
||||
screenWidth: number = 640;
|
||||
verticalScreenLines: number = 6;
|
||||
horizontalsScreenLines: number = 1;
|
||||
@StorageLink('mainWindow') mainWindow: Promise<window.Window> | undefined = undefined;
|
||||
@State fontSize: number = 1;
|
||||
@State maxLines: number = 1;
|
||||
@StorageProp('windowStandardHeight') windowStandardHeight: number = 0;
|
||||
cancel: () => void = () => {
|
||||
}
|
||||
confirm: () => void = () => {
|
||||
}
|
||||
|
||||
build() {
|
||||
if (this.TabTitleBarDialog) {
|
||||
Column() {
|
||||
Image(this.TabTitleDialog.value)
|
||||
.width(IMAGE_SIZE)
|
||||
.height(IMAGE_SIZE)
|
||||
.margin({
|
||||
top: $r('sys.float.padding_level24'),
|
||||
bottom: $r('sys.float.padding_level8'),
|
||||
})
|
||||
.fillColor($r('sys.color.icon_primary'))
|
||||
Column() {
|
||||
Text(this.TabTitleBarDialog)
|
||||
.fontSize(TEXT_EDITABLE_DIALOG)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.maxLines(this.maxLines)
|
||||
.width('100%')
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor($r('sys.color.font_primary'))
|
||||
}
|
||||
.width('100%')
|
||||
.padding({
|
||||
left: $r('sys.float.padding_level4'),
|
||||
right: $r('sys.float.padding_level4'),
|
||||
bottom: $r('sys.float.padding_level12'),
|
||||
})
|
||||
}
|
||||
.width(this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG)
|
||||
.constraintSize({ minHeight: this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG })
|
||||
.backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK)
|
||||
.shadow(ShadowStyle.OUTER_DEFAULT_LG)
|
||||
.borderRadius($r('sys.float.corner_radius_level10'))
|
||||
} else {
|
||||
Column() {
|
||||
Image(this.TabTitleDialog.value)
|
||||
.width(IMAGE_SIZE)
|
||||
.height(IMAGE_SIZE)
|
||||
.fillColor($r('sys.color.icon_primary'))
|
||||
}
|
||||
.width(this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG)
|
||||
.constraintSize({ minHeight: this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG })
|
||||
.backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK)
|
||||
.shadow(ShadowStyle.OUTER_DEFAULT_LG)
|
||||
.borderRadius($r('sys.float.corner_radius_level10'))
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
}
|
||||
|
||||
async aboutToAppear(): Promise<void> {
|
||||
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
|
||||
this.mainWindowStage = context.windowStage.getMainWindowSync();
|
||||
let properties: window.WindowProperties = this.mainWindowStage.getWindowProperties();
|
||||
let rect = properties.windowRect;
|
||||
if (px2vp(rect.height) > this.screenWidth) {
|
||||
this.maxLines = this.verticalScreenLines;
|
||||
} else {
|
||||
this.maxLines = this.horizontalsScreenLines;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user