mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-28 00:33:06 +08:00
[feat] add HarmonyOS desktop and mobile clients,issue #117
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import { DesktopEvent, DesktopHost } from './DesktopHost';
|
||||
import { KeyboardHost } from './KeyboardHost';
|
||||
|
||||
|
||||
// This host owns only the native surface and event delivery. All visible
|
||||
// application controls are compiled from apps/desktop's existing Slint files.
|
||||
@Entry({ useSharedStorage: true })
|
||||
@Component
|
||||
struct Index {
|
||||
private surface: XComponentController = new XComponentController();
|
||||
private keyboard: KeyboardHost = new KeyboardHost();
|
||||
private surfaceId: string = '';
|
||||
|
||||
private send(event: DesktopEvent): void {
|
||||
event.surface = this.surfaceId;
|
||||
DesktopHost.send(event);
|
||||
}
|
||||
@LocalStorageProp('slintWindowId') private windowId: number = 1;
|
||||
|
||||
aboutToDisappear(): void {
|
||||
this.keyboard.reset();
|
||||
if (this.surfaceId.length === 0) return;
|
||||
this.send({ op: 'detach', id: this.windowId });
|
||||
this.surfaceId = '';
|
||||
}
|
||||
|
||||
build() {
|
||||
Stack() {
|
||||
XComponent({ id: 'slint-desktop', type: XComponentType.SURFACE, controller: this.surface })
|
||||
.width('100%').height('100%')
|
||||
.onSizeChange((_old: SizeOptions, size: SizeOptions) => {
|
||||
this.surface.setXComponentSurfaceSize({ surfaceWidth: Math.round(vp2px(Number(size.width))),
|
||||
surfaceHeight: Math.round(vp2px(Number(size.height))) });
|
||||
this.send({ op: 'redraw', id: this.windowId });
|
||||
})
|
||||
.onLoad(() => {
|
||||
this.surfaceId = this.surface.getXComponentSurfaceId();
|
||||
this.send({ op: 'attach', id: this.windowId, surface: this.surface.getXComponentSurfaceId(),
|
||||
density: this.getUIContext().vp2px(1) });
|
||||
})
|
||||
.onDestroy(() => this.aboutToDisappear())
|
||||
// A focusable leaf is required: an empty Column is a focus scope and
|
||||
// receives touch events but cannot retain hardware keyboard focus.
|
||||
Text('').id('slintInput').width('100%').height('100%').focusable(true).defaultFocus(true).focusOnTouch(true)
|
||||
.onBlur(() => this.keyboard.reset())
|
||||
.onTouch((event: TouchEvent) => {
|
||||
if (event.type === TouchType.Down) this.getUIContext().getFocusController().requestFocus('slintInput');
|
||||
if (event.source === SourceType.Mouse) return;
|
||||
if (event.changedTouches.length === 0) return;
|
||||
const p = event.changedTouches[0];
|
||||
const kind = event.type === TouchType.Down ? 0 : event.type === TouchType.Up ? 1 :
|
||||
event.type === TouchType.Cancel ? 3 : 2;
|
||||
this.send({ op: 'pointer', id: this.windowId, kind, x: p.x, y: p.y, button: 0 });
|
||||
})
|
||||
.onMouse((event: MouseEvent) => {
|
||||
if (event.action === MouseAction.Press) this.getUIContext().getFocusController().requestFocus('slintInput');
|
||||
const kind = event.action === MouseAction.Press ? 0 : event.action === MouseAction.Release ? 1 : 2;
|
||||
this.send({ op: 'pointer', id: this.windowId, kind, x: event.x, y: event.y,
|
||||
button: event.button === MouseButton.Right ? 1 : event.button === MouseButton.Middle ? 2 : 0 });
|
||||
event.stopPropagation();
|
||||
})
|
||||
.onHover((hovered: boolean) => {
|
||||
if (!hovered) this.send({ op: 'pointerExit', id: this.windowId });
|
||||
})
|
||||
.onKeyPreIme((event: KeyEvent) => this.keyboard.preIme(event, this.windowId, (reply: DesktopEvent) => this.send(reply)))
|
||||
.onKeyEvent((event: KeyEvent) => {
|
||||
this.send(KeyboardHost.event(event, this.windowId));
|
||||
event.stopPropagation();
|
||||
})
|
||||
.onAxisEvent((event: AxisEvent) => {
|
||||
this.send({ op: 'scroll', id: this.windowId, x: event.x, y: event.y,
|
||||
dx: -event.getHorizontalAxisValue(), dy: -event.getVerticalAxisValue() });
|
||||
})
|
||||
}.width('100%').height('100%').backgroundColor(Color.White)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user