Skip to content

Commit

Permalink
feat(api): add toIpc method on dpi types, add more constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir committed Oct 2, 2024
1 parent 6cfe7ed commit bee00b4
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 200 deletions.
5 changes: 5 additions & 0 deletions .changes/api-toIpc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tauri-apps": "patch:feat"
---

Add to `toIpc` method on `PhysicalSize`, `PhysicalPosition`, `LogicalSize` and `LogicalPosition` to convert it into IPC-compatible value that can be deserialized correctly on the Rust side into its equivalent struct.
2 changes: 1 addition & 1 deletion crates/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

205 changes: 187 additions & 18 deletions packages/api/src/dpi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,40 @@
* @since 2.0.0
*/
class LogicalSize {
type = 'Logical'
type = 'Logical' as const
width: number
height: number

constructor(width: number, height: number) {
this.width = width
this.height = height
constructor(width: number, height: number)
constructor(objcet: { Logical: { width: number; height: number } })
constructor(objcet: { width: number; height: number })
constructor(
...args:
| [number, number]
| [{ width: number; height: number }]
| [{ Logical: { width: number; height: number } }]
) {
if (args.length === 1) {
if ('Logical' in args[0]) {
this.width = args[0].Logical.width
this.height = args[0].Logical.height
} else {
this.width = args[0].width
this.height = args[0].height
}
} else {
this.width = args[0]
this.height = args[1]
}
}

/**
* Converts the logical size to a physical one.
* @example
* ```typescript
* import { LogicalSize } from '@tauri-apps/api/dpi';
* import { getCurrentWindow } from '@tauri-apps/api/window';
*
* const appWindow = getCurrentWindow();
* const factor = await appWindow.scaleFactor();
* const size = new LogicalSize(400, 500);
Expand All @@ -33,6 +53,29 @@ class LogicalSize {
toPhysical(scaleFactor: number): PhysicalSize {
return new PhysicalSize(this.width * scaleFactor, this.height * scaleFactor)
}

/**
* Converts this size into IPC-compatible value, so it can be
* deserialized correctly on the Rust side using `tauri::LogicalSize` struct.
* @example
* ```typescript
* import { LogicalSize } from '@tauri-apps/api/dpi';
* import { invoke } from '@tauri-apps/api/core';
*
* const size = new LogicalSize(400, 500);
* await invoke("do_something_with_size", { size: size.toIpc() })
* ```
*
* @since 2.0.0
*/
toIpc(): { Logical: { width: number; height: number } } {
return {
Logical: {
width: this.width,
height: this.height
}
}
}
}

/**
Expand All @@ -41,13 +84,31 @@ class LogicalSize {
* @since 2.0.0
*/
class PhysicalSize {
type = 'Physical'
type = 'Physical' as const
width: number
height: number

constructor(width: number, height: number) {
this.width = width
this.height = height
constructor(width: number, height: number)
constructor(objcet: { Physical: { width: number; height: number } })
constructor(objcet: { width: number; height: number })
constructor(
...args:
| [number, number]
| [{ width: number; height: number }]
| [{ Physical: { width: number; height: number } }]
) {
if (args.length === 1) {
if ('Physical' in args[0]) {
this.width = args[0].Physical.width
this.height = args[0].Physical.height
} else {
this.width = args[0].width
this.height = args[0].height
}
} else {
this.width = args[0]
this.height = args[1]
}
}

/**
Expand All @@ -57,13 +118,36 @@ class PhysicalSize {
* import { getCurrentWindow } from '@tauri-apps/api/window';
* const appWindow = getCurrentWindow();
* const factor = await appWindow.scaleFactor();
* const size = await appWindow.innerSize();
* const size = await appWindow.innerSize(); // PhysicalSize
* const logical = size.toLogical(factor);
* ```
*/
toLogical(scaleFactor: number): LogicalSize {
return new LogicalSize(this.width / scaleFactor, this.height / scaleFactor)
}

/**
* Converts this size into IPC-compatible value, so it can be
* deserialized correctly on the Rust side using `tauri::PhysicalSize` struct.
* @example
* ```typescript
* import { PhysicalSize } from '@tauri-apps/api/dpi';
* import { invoke } from '@tauri-apps/api/core';
*
* const size = new PhysicalSize(400, 500);
* await invoke("do_something_with_size", { size: size.toIpc() })
* ```
*
* @since 2.0.0
*/
toIpc(): { Physical: { width: number; height: number } } {
return {
Physical: {
width: this.width,
height: this.height
}
}
}
}

/**
Expand All @@ -72,20 +156,40 @@ class PhysicalSize {
* @since 2.0.0
*/
class LogicalPosition {
type = 'Logical'
type = 'Logical' as const
x: number
y: number

constructor(x: number, y: number) {
this.x = x
this.y = y
constructor(x: number, y: number)
constructor(objcet: { Logical: { x: number; y: number } })
constructor(objcet: { x: number; y: number })
constructor(
...args:
| [number, number]
| [{ x: number; y: number }]
| [{ Logical: { x: number; y: number } }]
) {
if (args.length === 1) {
if ('Logical' in args[0]) {
this.x = args[0].Logical.x
this.y = args[0].Logical.y
} else {
this.x = args[0].x
this.y = args[0].y
}
} else {
this.x = args[0]
this.y = args[1]
}
}

/**
* Converts the logical position to a physical one.
* @example
* ```typescript
* import { LogicalPosition } from '@tauri-apps/api/dpi';
* import { getCurrentWindow } from '@tauri-apps/api/window';
*
* const appWindow = getCurrentWindow();
* const factor = await appWindow.scaleFactor();
* const position = new LogicalPosition(400, 500);
Expand All @@ -97,6 +201,29 @@ class LogicalPosition {
toPhysical(scaleFactor: number): PhysicalPosition {
return new PhysicalPosition(this.x * scaleFactor, this.x * scaleFactor)
}

/**
* Converts this position into IPC-compatible value, so it can be
* deserialized correctly on the Rust side using `tauri::LogicalPosition` struct.
* @example
* ```typescript
* import { LogicalPosition } from '@tauri-apps/api/dpi';
* import { invoke } from '@tauri-apps/api/core';
*
* const position = new LogicalPosition(400, 500);
* await invoke("do_something_with_position", { size: size.toIpc() })
* ```
*
* @since 2.0.0
*/
toIpc(): { Logical: { x: number; y: number } } {
return {
Logical: {
x: this.x,
y: this.y
}
}
}
}

/**
Expand All @@ -105,29 +232,71 @@ class LogicalPosition {
* @since 2.0.0
*/
class PhysicalPosition {
type = 'Physical'
type = 'Physical' as const
x: number
y: number

constructor(x: number, y: number) {
this.x = x
this.y = y
constructor(x: number, y: number)
constructor(objcet: { Physical: { x: number; y: number } })
constructor(objcet: { x: number; y: number })
constructor(
...args:
| [number, number]
| [{ x: number; y: number }]
| [{ Physical: { x: number; y: number } }]
) {
if (args.length === 1) {
if ('Physical' in args[0]) {
this.x = args[0].Physical.x
this.y = args[0].Physical.y
} else {
this.x = args[0].x
this.y = args[0].y
}
} else {
this.x = args[0]
this.y = args[1]
}
}

/**
* Converts the physical position to a logical one.
* @example
* ```typescript
* import { getCurrentWindow } from '@tauri-apps/api/window';
*
* const appWindow = getCurrentWindow();
* const factor = await appWindow.scaleFactor();
* const position = await appWindow.innerPosition();
* const position = await appWindow.innerPosition(); // PhysicalPosition
* const logical = position.toLogical(factor);
* ```
*/
toLogical(scaleFactor: number): LogicalPosition {
return new LogicalPosition(this.x / scaleFactor, this.y / scaleFactor)
}

/**
* Converts this position into IPC-compatible value, so it can be
* deserialized correctly on the Rust side using `tauri::PhysicalPosition` struct.
* @example
* ```typescript
* import { PhysicalPosition } from '@tauri-apps/api/dpi';
* import { invoke } from '@tauri-apps/api/core';
*
* const position = new PhysicalPosition(400, 500);
* await invoke("do_something_with_position", { size: size.toIpc() })
* ```
*
* @since 2.0.0
*/
toIpc(): { Physical: { x: number; y: number } } {
return {
Physical: {
x: this.x,
y: this.y
}
}
}
}

export { LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize }
10 changes: 1 addition & 9 deletions packages/api/src/menu/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,19 +243,11 @@ export class Menu extends MenuItemBase {
at?: PhysicalPosition | LogicalPosition,
window?: Window
): Promise<void> {
let atValue = null
if (at) {
atValue = {} as Record<string, unknown>
atValue[`${at instanceof PhysicalPosition ? 'Physical' : 'Logical'}`] = {
x: at.x,
y: at.y
}
}
return invoke('plugin:menu|popup', {
rid: this.rid,
kind: this.kind,
window: window?.label ?? null,
at: atValue
at: at?.toIpc()
})
}

Expand Down
10 changes: 1 addition & 9 deletions packages/api/src/menu/submenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,19 +243,11 @@ export class Submenu extends MenuItemBase {
at?: PhysicalPosition | LogicalPosition,
window?: Window
): Promise<void> {
let atValue = null
if (at) {
atValue = {} as Record<string, unknown>
atValue[`${at instanceof PhysicalPosition ? 'Physical' : 'Logical'}`] = {
x: at.x,
y: at.y
}
}
return invoke('plugin:menu|popup', {
rid: this.rid,
kind: this.kind,
window: window?.label ?? null,
at: atValue
at: at?.toIpc()
})
}

Expand Down
13 changes: 3 additions & 10 deletions packages/api/src/tray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,16 +290,9 @@ export class TrayIcon extends Resource {
function mapEvent(e: RustTrayIconEvent): TrayIconEvent {
const out = e as unknown as TrayIconEvent

out.position = new PhysicalPosition(e.position.x, e.position.y)

out.rect.position = new PhysicalPosition(
e.rect.position.Physical.x,
e.rect.position.Physical.y
)
out.rect.size = new PhysicalSize(
e.rect.size.Physical.width,
e.rect.size.Physical.height
)
out.position = new PhysicalPosition(e.position)
out.rect.position = new PhysicalPosition(e.rect.position)
out.rect.size = new PhysicalSize(e.rect.size)

return out
}
Loading

0 comments on commit bee00b4

Please sign in to comment.