Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor DPI scaling and fix the GTK implementation. #904

Merged
merged 29 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
08aa411
Fix DPI support in GTK.
xStrom May 4, 2020
bc19b79
Make X11 compile with Scale.
xStrom May 4, 2020
11014f3
Update float-cmp to 0.8.0.
xStrom May 4, 2020
0a204e4
Refactor Windows shell code to use new Scale system.
xStrom May 5, 2020
78700b2
Add more Windows changes.
xStrom May 5, 2020
0f1529f
Improve Windows DPI code.
xStrom May 6, 2020
8b9a8b0
Improve DPI docs.
xStrom May 6, 2020
6205c93
Move to a more pixel alignment friendly scaling strategy.
xStrom May 6, 2020
b96c747
Add new Scale support for X11/GTK.
xStrom May 6, 2020
05dd453
Fix macOS compiling with new Scale.
xStrom May 6, 2020
e1a7625
Add support for Scale in web.
xStrom May 6, 2020
bf4069d
Refactor shell errors.
xStrom May 6, 2020
1b6d7b8
Update changelog.
xStrom May 6, 2020
6a76556
Add scaling to new wheel events.
xStrom May 9, 2020
79012f9
Change points/pt to display points/dp.
xStrom May 9, 2020
38980c4
Fix scale in GTK wheel event handler.
xStrom May 9, 2020
28966e8
Implement Scalable for Vec2/Line/Insets.
xStrom May 9, 2020
59992ca
Fix web wheel event DPI handling.
xStrom May 11, 2020
a153627
Merge Cargo.lock.
xStrom May 16, 2020
b04b003
Make minor changes based on feedback.
xStrom May 16, 2020
d17bb2d
Split out ScaledArea from Scale.
xStrom May 16, 2020
dfe28d8
Add ScaledArea support for web.
xStrom May 16, 2020
048ac50
Add GTK support for ScaledArea.
xStrom May 16, 2020
04f2f5f
Add default implementations to Scale and ScaledArea.
xStrom May 16, 2020
bb7fe5c
Add a scale method to WinHandler.
xStrom May 16, 2020
516df21
Add changelog entry.
xStrom May 16, 2020
37a2cc5
Add more documentation about display points.
xStrom May 16, 2020
16ec5af
Do some minor cleanup.
xStrom May 16, 2020
060dc4f
Delete some Scale code.
xStrom May 18, 2020
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
- `Env` and `Key` gained methods for inspecting an `Env` at runtime ([#880] by [@Zarenor])
- `UpdateCtx::request_timer` and `UpdateCtx::request_anim_frame`. ([#898] by [@finnerale])
- `LifeCycleCtx::request_timer`. ([#954] by [@xStrom])
- `scale` method to `WinHandler`. ([#904] by [@xStrom])
- `WinHandler::scale` method to inform of scale changes. ([#904] by [@xStrom])
- `UpdateCtx::size` and `LifeCycleCtx::size`. ([#917] by [@jneem])
- `WidgetExt::debug_widget_id`, for displaying widget ids on hover. ([#876] by [@cmyr])
- `im` feature, with `Data` support for the [`im` crate](https://docs.rs/im/) collections. ([#924] by [@cmyr])
Expand All @@ -61,6 +63,8 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
- Global `Application` associated functions are instance methods instead, e.g. `Application::global().quit()` instead of the old `Application::quit()`. ([#763] by [@xStrom])
- Timer events will only be delivered to the widgets that requested them. ([#831] by [@sjoshid])
- `Event::Wheel` now contains a `MouseEvent` structure. ([#895] by [@teddemunnik])
- The `WindowHandle::get_dpi` method got replaced by `WindowHandle::get_scale`. ([#904] by [@xStrom])
- The `WinHandler::size` method now gets a `Size` in display points. ([#904] by [@xStrom])
- `AppDelegate::command` now receives a `Target` instead of a `&Target`. ([#909] by [@xStrom])
- `SHOW_WINDOW` and `CLOSE_WINDOW` commands now only use `Target` to determine the affected window. ([#928] by [@finnerale])
- Replaced `NEW_WINDOW`, `SET_MENU` and `SHOW_CONTEXT_MENU` commands with methods on `EventCtx` and `DelegateCtx`. ([#931] by [@finnerale])
Expand Down Expand Up @@ -94,6 +98,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
- X11: Support individual window closing. ([#900] by [@xStrom])
- X11: Support `Application::quit`. ([#900] by [@xStrom])
- GTK: Support file filters in open/save dialogs. ([#903] by [@jneem])
- GTK: Support DPI values other than 96. ([#904] by [@xStrom])
- X11: Support key and mouse button state. ([#920] by [@jneem])
- Routing `LifeCycle::FocusChanged` to descendant widgets. ([#925] by [@yrns])
- Built-in open and save menu items now show the correct label and submit the right commands. ([#930] by [@finnerale])
Expand Down Expand Up @@ -125,6 +130,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
- GTK: Refactored `Application` to use the new structure. ([#892] by [@xStrom])
- X11: Refactored `Application` to use the new structure. ([#894] by [@xStrom])
- X11: Refactored `Window` to support some reentrancy and invalidation. ([#894] by [@xStrom])
- Refactored DPI scaling. ([#904] by [@xStrom])
- Added docs generation testing for all features. ([#942] by [@xStrom])

### Outside News
Expand Down Expand Up @@ -183,6 +189,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
[#898]: https://github.com/xi-editor/druid/pull/898
[#900]: https://github.com/xi-editor/druid/pull/900
[#903]: https://github.com/xi-editor/druid/pull/903
[#904]: https://github.com/xi-editor/druid/pull/904
[#905]: https://github.com/xi-editor/druid/pull/905
[#909]: https://github.com/xi-editor/druid/pull/909
[#917]: https://github.com/xi-editor/druid/pull/917
Expand Down
8 changes: 7 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/src/widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ widgets].

Widgets are intended to be modular and composable, not monolithic. For instance,
widgets generally do not control their own alignment or padding; if you have
a label, and you would like it to have 8px of horizontal padding and 4px of
a label, and you would like it to have 8dp of horizontal padding and 4dp of
vertical padding, you can just do,

```rust,noplaypen
Expand Down
22 changes: 9 additions & 13 deletions druid-shell/examples/invalidate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ use std::any::Any;

use std::time::{Duration, Instant};

use druid_shell::kurbo::{Point, Rect};
use druid_shell::kurbo::{Point, Rect, Size};
use druid_shell::piet::{Color, Piet, RenderContext};

use druid_shell::{Application, TimerToken, WinHandler, WindowBuilder, WindowHandle};

struct InvalidateTest {
handle: WindowHandle,
size: (f64, f64),
size: Size,
start_time: Instant,
color: Color,
rect: Rect,
Expand All @@ -39,10 +39,10 @@ impl InvalidateTest {
(_, _) => Color::rgb8(r, g, b.wrapping_add(10)),
};

self.rect.x0 = (self.rect.x0 + 5.0) % self.size.0;
self.rect.x1 = (self.rect.x1 + 5.5) % self.size.0;
self.rect.y0 = (self.rect.y0 + 3.0) % self.size.1;
self.rect.y1 = (self.rect.y1 + 3.5) % self.size.1;
self.rect.x0 = (self.rect.x0 + 5.0) % self.size.width;
self.rect.x1 = (self.rect.x1 + 5.5) % self.size.width;
self.rect.y0 = (self.rect.y0 + 3.0) % self.size.height;
self.rect.y1 = (self.rect.y1 + 3.5) % self.size.height;
}
}

Expand All @@ -63,12 +63,8 @@ impl WinHandler for InvalidateTest {
false
}

fn size(&mut self, width: u32, height: u32) {
let dpi = self.handle.get_dpi();
let dpi_scale = dpi as f64 / 96.0;
let width_f = (width as f64) / dpi_scale;
let height_f = (height as f64) / dpi_scale;
self.size = (width_f, height_f);
fn size(&mut self, size: Size) {
self.size = size;
}

fn command(&mut self, id: u32) {
Expand All @@ -91,7 +87,7 @@ fn main() {
let app = Application::new().unwrap();
let mut builder = WindowBuilder::new(app.clone());
let inv_test = InvalidateTest {
size: Default::default(),
size: Size::ZERO,
handle: Default::default(),
start_time: Instant::now(),
rect: Rect::from_origin_size(Point::ZERO, (10.0, 20.0)),
Expand Down
23 changes: 11 additions & 12 deletions druid-shell/examples/perftest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::any::Any;

use time::Instant;

use piet_common::kurbo::{Line, Rect};
use piet_common::kurbo::{Line, Rect, Size};
use piet_common::{Color, FontBuilder, Piet, RenderContext, Text, TextLayoutBuilder};

use druid_shell::{Application, KeyEvent, WinHandler, WindowBuilder, WindowHandle};
Expand All @@ -26,7 +26,7 @@ const FG_COLOR: Color = Color::rgb8(0xf0, 0xf0, 0xea);

struct PerfTest {
handle: WindowHandle,
size: (f64, f64),
size: Size,
start_time: Instant,
last_time: Instant,
}
Expand All @@ -37,11 +37,14 @@ impl WinHandler for PerfTest {
}

fn paint(&mut self, piet: &mut Piet, _: Rect) -> bool {
let (width, height) = self.size;
let rect = Rect::new(0.0, 0.0, width, height);
let rect = self.size.to_rect();
piet.fill(rect, &BG_COLOR);

piet.stroke(Line::new((0.0, height), (width, 0.0)), &FG_COLOR, 1.0);
piet.stroke(
Line::new((0.0, self.size.height), (self.size.width, 0.0)),
&FG_COLOR,
1.0,
);

let current_ns = (Instant::now() - self.start_time).whole_nanoseconds();
let th = ::std::f64::consts::PI * (current_ns as f64) * 2e-9;
Expand Down Expand Up @@ -98,12 +101,8 @@ impl WinHandler for PerfTest {
false
}

fn size(&mut self, width: u32, height: u32) {
let dpi = self.handle.get_dpi();
let dpi_scale = dpi as f64 / 96.0;
let width_f = (width as f64) / dpi_scale;
let height_f = (height as f64) / dpi_scale;
self.size = (width_f, height_f);
fn size(&mut self, size: Size) {
self.size = size;
}

fn destroy(&mut self) {
Expand All @@ -119,7 +118,7 @@ fn main() {
let app = Application::new().unwrap();
let mut builder = WindowBuilder::new(app.clone());
let perf_test = PerfTest {
size: Default::default(),
size: Size::ZERO,
handle: Default::default(),
start_time: time::Instant::now(),
last_time: time::Instant::now(),
Expand Down
15 changes: 5 additions & 10 deletions druid-shell/examples/shello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use std::any::Any;

use druid_shell::kurbo::{Line, Rect};
use druid_shell::kurbo::{Line, Rect, Size};
use druid_shell::piet::{Color, RenderContext};

use druid_shell::{
Expand All @@ -27,7 +27,7 @@ const FG_COLOR: Color = Color::rgb8(0xf0, 0xf0, 0xea);

#[derive(Default)]
struct HelloState {
size: (f64, f64),
size: Size,
handle: WindowHandle,
}

Expand All @@ -37,8 +37,7 @@ impl WinHandler for HelloState {
}

fn paint(&mut self, piet: &mut piet_common::Piet, _: Rect) -> bool {
let (width, height) = self.size;
let rect = Rect::new(0.0, 0.0, width, height);
let rect = self.size.to_rect();
piet.fill(rect, &BG_COLOR);
piet.stroke(Line::new((10.0, 50.0), (90.0, 90.0)), &FG_COLOR, 1.0);
false
Expand Down Expand Up @@ -92,12 +91,8 @@ impl WinHandler for HelloState {
println!("timer fired: {:?}", id);
}

fn size(&mut self, width: u32, height: u32) {
let dpi = self.handle.get_dpi();
let dpi_scale = dpi as f64 / 96.0;
let width_f = (width as f64) / dpi_scale;
let height_f = (height as f64) / dpi_scale;
self.size = (width_f, height_f);
fn size(&mut self, size: Size) {
self.size = size;
}

fn destroy(&mut self) {
Expand Down
62 changes: 58 additions & 4 deletions druid-shell/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ use std::fmt;

use crate::platform::error as platform;

/// Error codes. At the moment, this is little more than HRESULT, but that
/// might change.
/// Shell errors.
#[derive(Debug, Clone)]
pub enum Error {
/// The Application instance has already been created.
ApplicationAlreadyExists,
Other(&'static str),
/// The window has already been destroyed.
WindowDropped,
/// Runtime borrow failure.
BorrowError(BorrowError),
/// Platform specific error.
Platform(platform::Error),
/// Other miscellaneous error.
Other(&'static str),
}

impl fmt::Display for Error {
Expand All @@ -33,8 +39,10 @@ impl fmt::Display for Error {
Error::ApplicationAlreadyExists => {
write!(f, "An application instance has already been created.")
}
Error::WindowDropped => write!(f, "The window has already been destroyed."),
Error::BorrowError(err) => fmt::Display::fmt(err, f),
Error::Platform(err) => fmt::Display::fmt(err, f),
Error::Other(s) => write!(f, "{}", s),
Error::Platform(p) => fmt::Display::fmt(&p, f),
}
}
}
Expand All @@ -46,3 +54,49 @@ impl From<platform::Error> for Error {
Error::Platform(src)
}
}

/// Runtime borrow failure.
#[derive(Debug, Clone)]
pub struct BorrowError {
location: &'static str,
target: &'static str,
mutable: bool,
}

impl BorrowError {
pub fn new(location: &'static str, target: &'static str, mutable: bool) -> BorrowError {
BorrowError {
location,
target,
mutable,
}
}
}

impl fmt::Display for BorrowError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
if self.mutable {
// Mutable borrow fails when any borrow exists
write!(
f,
"{} was already borrowed in {}",
self.target, self.location
)
} else {
// Regular borrow fails when a mutable borrow exists
write!(
f,
"{} was already mutably borrowed in {}",
self.target, self.location
)
}
}
}

impl std::error::Error for BorrowError {}

impl From<BorrowError> for Error {
fn from(src: BorrowError) -> Error {
Error::BorrowError(src)
}
}
2 changes: 2 additions & 0 deletions druid-shell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ mod keycodes;
mod menu;
mod mouse;
mod platform;
mod scale;
mod util;
mod window;

Expand All @@ -48,6 +49,7 @@ pub use keyboard::{KeyEvent, KeyModifiers};
pub use keycodes::KeyCode;
pub use menu::Menu;
pub use mouse::{Cursor, MouseButton, MouseButtons, MouseEvent};
pub use scale::{Scalable, Scale, ScaledArea};
pub use window::{
IdleHandle, IdleToken, Text, TimerToken, WinHandler, WindowBuilder, WindowHandle,
};
4 changes: 2 additions & 2 deletions druid-shell/src/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ use crate::keyboard::KeyModifiers;
/// receiving a move event before another mouse event.
#[derive(Debug, Clone, PartialEq)]
pub struct MouseEvent {
/// The location of the mouse in the current window.
/// The location of the mouse in [display points] in relation to the current window.
///
/// This is in px units not device pixels, that is, adjusted for hi-dpi.
/// [display points]: struct.Scale.html
pub pos: Point,
/// Mouse buttons being held down during a move or after a click event.
/// Thus it will contain the `button` that triggered a mouse-down event,
Expand Down
Loading