Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 38 additions & 37 deletions internal/backends/qt/qt_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2066,43 +2066,6 @@ impl WindowAdapter for QtWindow {
fn internal(&self, _: i_slint_core::InternalToken) -> Option<&dyn WindowAdapterInternal> {
Some(self)
}
}

fn into_qsize(logical_size: i_slint_core::api::LogicalSize) -> qttypes::QSize {
qttypes::QSize {
width: logical_size.width.round() as _,
height: logical_size.height.round() as _,
}
}

impl WindowAdapterInternal for QtWindow {
fn register_item_tree(&self) {
self.tree_structure_changed.replace(true);
}

fn unregister_item_tree(
&self,
_component: ItemTreeRef,
_: &mut dyn Iterator<Item = Pin<ItemRef<'_>>>,
) {
self.tree_structure_changed.replace(true);
}

fn create_popup(&self, geometry: LogicalRect) -> Option<Rc<dyn WindowAdapter>> {
let popup_window = QtWindow::new();

let size = qttypes::QSize { width: geometry.width() as _, height: geometry.height() as _ };

let popup_ptr = popup_window.widget_ptr();
let pos = qttypes::QPoint { x: geometry.origin.x as _, y: geometry.origin.y as _ };
let widget_ptr = self.widget_ptr();
cpp! {unsafe [widget_ptr as "QWidget*", popup_ptr as "QWidget*", pos as "QPoint", size as "QSize"] {
popup_ptr->setParent(widget_ptr, Qt::Popup);
popup_ptr->setGeometry(QRect(pos + widget_ptr->mapToGlobal(QPoint(0,0)), size));
popup_ptr->show();
}};
Some(popup_window as _)
}

fn set_mouse_cursor(&self, cursor: MouseCursor) {
let widget_ptr = self.widget_ptr();
Expand Down Expand Up @@ -2142,6 +2105,44 @@ impl WindowAdapterInternal for QtWindow {
widget_ptr->setCursor(QCursor{cursor_shape});
}};
}
}

fn into_qsize(logical_size: i_slint_core::api::LogicalSize) -> qttypes::QSize {
qttypes::QSize {
width: logical_size.width.round() as _,
height: logical_size.height.round() as _,
}
}

impl WindowAdapterInternal for QtWindow {
fn register_item_tree(&self) {
self.tree_structure_changed.replace(true);
}

fn unregister_item_tree(
&self,
_component: ItemTreeRef,
_: &mut dyn Iterator<Item = Pin<ItemRef<'_>>>,
) {
self.tree_structure_changed.replace(true);
}

fn create_popup(&self, geometry: LogicalRect) -> Option<Rc<dyn WindowAdapter>> {
let popup_window = QtWindow::new();

let size = qttypes::QSize { width: geometry.width() as _, height: geometry.height() as _ };

let popup_ptr = popup_window.widget_ptr();
let pos = qttypes::QPoint { x: geometry.origin.x as _, y: geometry.origin.y as _ };
let widget_ptr = self.widget_ptr();
cpp! {unsafe [widget_ptr as "QWidget*", popup_ptr as "QWidget*", pos as "QPoint", size as "QSize"] {
popup_ptr->setParent(widget_ptr, Qt::Popup);
popup_ptr->setGeometry(QRect(pos + widget_ptr->mapToGlobal(QPoint(0,0)), size));
popup_ptr->show();
}};
Some(popup_window as _)
}


fn input_method_request(&self, request: i_slint_core::window::InputMethodRequest) {
let widget_ptr = self.widget_ptr();
Expand Down
8 changes: 4 additions & 4 deletions internal/backends/testing/testing_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,6 @@ impl WindowAdapterInternal for TestingWindow {
fn input_method_request(&self, request: i_slint_core::window::InputMethodRequest) {
self.ime_requests.borrow_mut().push(request)
}

fn set_mouse_cursor(&self, cursor: i_slint_core::items::MouseCursor) {
self.mouse_cursor.set(cursor);
}
}

impl WindowAdapter for TestingWindow {
Expand Down Expand Up @@ -159,6 +155,10 @@ impl WindowAdapter for TestingWindow {
fn internal(&self, _: i_slint_core::InternalToken) -> Option<&dyn WindowAdapterInternal> {
Some(self)
}

fn set_mouse_cursor(&self, cursor: i_slint_core::items::MouseCursor) {
self.mouse_cursor.set(cursor);
}
}

impl RendererSealed for TestingWindow {
Expand Down
4 changes: 2 additions & 2 deletions internal/backends/winit/winitwindowadapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1244,9 +1244,7 @@ impl WindowAdapter for WinitWindowAdapter {
fn internal(&self, _: corelib::InternalToken) -> Option<&dyn WindowAdapterInternal> {
Some(self)
}
}

impl WindowAdapterInternal for WinitWindowAdapter {
fn set_mouse_cursor(&self, cursor: MouseCursor) {
let winit_cursor = match cursor {
MouseCursor::Default => winit::window::CursorIcon::Default,
Expand Down Expand Up @@ -1284,7 +1282,9 @@ impl WindowAdapterInternal for WinitWindowAdapter {
winit_window.set_cursor(winit_cursor);
}
}
}

impl WindowAdapterInternal for WinitWindowAdapter {
fn input_method_request(&self, request: corelib::window::InputMethodRequest) {
#[cfg(not(target_arch = "wasm32"))]
if let Some(winit_window) = self.winit_window_or_none.borrow().as_window() {
Expand Down
134 changes: 64 additions & 70 deletions internal/common/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,76 +177,6 @@ macro_rules! for_each_enums {
Forward,
}

/// This enum represents different types of mouse cursors. It's a subset of the mouse cursors available in CSS.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This didn't need to be moved. Makes the patch harder to review.

/// For details and pictograms see the [MDN Documentation for cursor](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#values).
/// Depending on the backend and used OS unidirectional resize cursors may be replaced with bidirectional ones.
enum MouseCursor {
/// The systems default cursor.
Default,
/// No cursor is displayed.
None,
//context_menu,
/// A cursor indicating help information.
Help,
/// A pointing hand indicating a link.
Pointer,
/// The program is busy but can still be interacted with.
Progress,
/// The program is busy.
Wait,
//cell,
/// A crosshair.
Crosshair,
/// A cursor indicating selectable text.
Text,
//vertical_text,
/// An alias or shortcut is being created.
Alias,
/// A copy is being created.
Copy,
/// Something is to be moved.
Move,
/// Something can't be dropped here.
NoDrop,
/// An action isn't allowed
NotAllowed,
/// Something is grabbable.
Grab,
/// Something is being grabbed.
Grabbing,
//all_scroll,
/// Indicating that a column is resizable horizontally.
ColResize,
/// Indicating that a row is resizable vertically.
RowResize,
/// Unidirectional resize north.
NResize,
/// Unidirectional resize east.
EResize,
/// Unidirectional resize south.
SResize,
/// Unidirectional resize west.
WResize,
/// Unidirectional resize north-east.
NeResize,
/// Unidirectional resize north-west.
NwResize,
/// Unidirectional resize south-east.
SeResize,
/// Unidirectional resize south-west.
SwResize,
/// Bidirectional resize east-west.
EwResize,
/// Bidirectional resize north-south.
NsResize,
/// Bidirectional resize north-east-south-west.
NeswResize,
/// Bidirectional resize north-west-south-east.
NwseResize,
//zoom_in,
//zoom_out,
}

/// This enum defines how the source image shall fit into an `Image` element.
enum ImageFit {
/// Scales and stretches the source image to fit the width and height of the `Image` element.
Expand Down Expand Up @@ -491,6 +421,70 @@ macro_rules! for_each_enums {
/// This variant is reported when the operating system is none of the above.
Other,
}

/// This enum represents different types of mouse cursors. It's a subset of the mouse cursors available in CSS.
/// For details and pictograms see the [MDN Documentation for cursor](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#values).
/// Depending on the backend and used OS unidirectional resize cursors may be replaced with bidirectional ones.
enum MouseCursor {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enum needs to be #[non_exhaustive] for compatibility with potential future cursor.

/// The system's default cursor.
Default,
/// No cursor is displayed.
None,
/// A cursor indicating help information.
Help,
/// A pointing hand indicating a link.
Pointer,
/// The program is busy but can still be interacted with.
Progress,
/// The program is busy.
Wait,
/// A crosshair.
Crosshair,
/// A cursor indicating selectable text.
Text,
/// An alias or shortcut is being created.
Alias,
/// A copy is being created.
Copy,
/// Something is to be moved.
Move,
/// Something can't be dropped here.
NoDrop,
/// An action isn't allowed.
NotAllowed,
/// Something is grabbable.
Grab,
/// Something is being grabbed.
Grabbing,
/// Indicating that a column is resizable horizontally.
ColResize,
/// Indicating that a row is resizable vertically.
RowResize,
/// Unidirectional resize north.
NResize,
/// Unidirectional resize east.
EResize,
/// Unidirectional resize south.
SResize,
/// Unidirectional resize west.
WResize,
/// Unidirectional resize north-east.
NeResize,
/// Unidirectional resize north-west.
NwResize,
/// Unidirectional resize south-east.
SeResize,
/// Unidirectional resize south-west.
SwResize,
/// Bidirectional resize east-west.
EwResize,
/// Bidirectional resize north-south.
NsResize,
/// Bidirectional resize north-east-south-west.
NeswResize,
/// Bidirectional resize north-west-south-east.
NwseResize,
}
];
};
}
6 changes: 6 additions & 0 deletions internal/core/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This module contains types that are public and re-exported in the slint-rs as we
pub use crate::future::*;
use crate::graphics::{Rgba8Pixel, SharedPixelBuffer};
use crate::input::{KeyEventType, MouseEvent};
pub use crate::items::MouseCursor;
use crate::window::{WindowAdapter, WindowInner};
use alloc::boxed::Box;
use alloc::string::String;
Expand Down Expand Up @@ -706,6 +707,11 @@ impl Window {
pub fn take_snapshot(&self) -> Result<SharedPixelBuffer<Rgba8Pixel>, PlatformError> {
self.0.window_adapter().renderer().take_snapshot()
}

/// Sets the mouse cursor for this window.
pub fn set_mouse_cursor(&self, cursor: crate::items::MouseCursor) {
self.0.window_adapter().set_mouse_cursor(cursor);
}
Comment on lines +711 to +714
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API shouldn't need to be there.
In order to set a mouse cursor on the window, one would use a TouchArea with a mouse-cursor property.

}

pub use crate::SharedString;
Expand Down
9 changes: 3 additions & 6 deletions internal/core/items/drag_n_drop.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// Copyright © SixtyFPS GmbH <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

use super::{
DropEvent, Item, ItemConsts, ItemRc, MouseCursor, PointerEventButton, RenderingResult,
};
use super::{DropEvent, Item, ItemConsts, ItemRc, PointerEventButton, RenderingResult};
use crate::input::{
FocusEvent, FocusEventResult, InputEventFilterResult, InputEventResult, KeyEvent,
KeyEventResult, MouseEvent,
};
use crate::item_rendering::{CachedRenderingData, ItemRenderer};
use crate::items::MouseCursor;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(a bit inconsistent to have some import through crates::items and some through super)

use crate::layout::{LayoutInfo, Orientation};
use crate::lengths::{LogicalPoint, LogicalRect, LogicalSize};
#[cfg(feature = "rtti")]
Expand Down Expand Up @@ -249,9 +248,7 @@ impl Item for DropArea {
let r = Self::FIELD_OFFSETS.can_drop.apply_pin(self).call(&(event.clone(),));
if r {
self.contains_drag.set(true);
if let Some(window_adapter) = window_adapter.internal(crate::InternalToken) {
window_adapter.set_mouse_cursor(MouseCursor::Copy);
}
window_adapter.set_mouse_cursor(MouseCursor::Copy);
InputEventResult::EventAccepted
} else {
self.contains_drag.set(false);
Expand Down
13 changes: 5 additions & 8 deletions internal/core/items/input_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@

use super::{
EventResult, FocusReasonArg, Item, ItemConsts, ItemRc, ItemRendererRef, KeyEventArg,
MouseCursor, PointerEvent, PointerEventArg, PointerEventButton, PointerEventKind,
PointerScrollEvent, PointerScrollEventArg, RenderingResult, VoidArg,
PointerEvent, PointerEventArg, PointerEventButton, PointerEventKind, PointerScrollEvent,
PointerScrollEventArg, RenderingResult, VoidArg,
};
use crate::api::LogicalPosition;
use crate::input::{
FocusEvent, FocusEventResult, FocusReason, InputEventFilterResult, InputEventResult, KeyEvent,
KeyEventResult, KeyEventType, MouseEvent,
};
use crate::item_rendering::CachedRenderingData;
use crate::items::MouseCursor;
use crate::layout::{LayoutInfo, Orientation};
use crate::lengths::{LogicalLength, LogicalPoint, LogicalRect, LogicalSize, PointLengths};
#[cfg(feature = "rtti")]
Expand Down Expand Up @@ -94,9 +95,7 @@ impl Item for TouchArea {
let hovering = !matches!(event, MouseEvent::Exit);
Self::FIELD_OFFSETS.has_hover.apply_pin(self).set(hovering);
if hovering {
if let Some(x) = window_adapter.internal(crate::InternalToken) {
x.set_mouse_cursor(self.mouse_cursor());
}
window_adapter.set_mouse_cursor(self.mouse_cursor());
}
InputEventFilterResult::ForwardAndInterceptGrab
}
Expand All @@ -109,9 +108,7 @@ impl Item for TouchArea {
) -> InputEventResult {
if matches!(event, MouseEvent::Exit) {
Self::FIELD_OFFSETS.has_hover.apply_pin(self).set(false);
if let Some(x) = window_adapter.internal(crate::InternalToken) {
x.set_mouse_cursor(MouseCursor::Default);
}
window_adapter.set_mouse_cursor(MouseCursor::Default);
}
if !self.enabled() {
return InputEventResult::EventIgnored;
Expand Down
9 changes: 3 additions & 6 deletions internal/core/items/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::input::{
KeyEvent, KeyboardModifiers, MouseEvent, StandardShortcut, TextShortcut,
};
use crate::item_rendering::{CachedRenderingData, ItemRenderer, RenderText};
use crate::items::MouseCursor;
use crate::layout::{LayoutInfo, Orientation};
use crate::lengths::{
LogicalLength, LogicalPoint, LogicalRect, LogicalSize, ScaleFactor, SizeLengths,
Expand Down Expand Up @@ -661,15 +662,11 @@ impl Item for TextInput {
self.paste_clipboard(window_adapter, self_rc, Clipboard::SelectionClipboard);
}
MouseEvent::Exit => {
if let Some(x) = window_adapter.internal(crate::InternalToken) {
x.set_mouse_cursor(super::MouseCursor::Default);
}
window_adapter.set_mouse_cursor(MouseCursor::Default);
self.as_ref().pressed.set(0)
}
MouseEvent::Moved { position } => {
if let Some(x) = window_adapter.internal(crate::InternalToken) {
x.set_mouse_cursor(super::MouseCursor::Text);
}
window_adapter.set_mouse_cursor(MouseCursor::Text);
let pressed = self.as_ref().pressed.get();
if pressed > 0 {
let clicked_offset =
Expand Down
Loading
Loading