print: Make preview size adaptive
Part-of: <https://gitlab.gnome.org/GNOME/loupe/-/merge_requests/240>
This commit is contained in:
parent
65af818567
commit
e6646bdbe3
3 changed files with 127 additions and 73 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<interface>
|
<interface>
|
||||||
<template class="LpPrint" parent="AdwWindow">
|
<template class="LpPrint" parent="AdwWindow">
|
||||||
<property name="default-width">600</property>
|
<property name="default-width">900</property>
|
||||||
|
<property name="default-height">650</property>
|
||||||
<signal name="notify::orientation" handler="orientation_changed" swapped="yes" />
|
<signal name="notify::orientation" handler="orientation_changed" swapped="yes" />
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutController">
|
<object class="GtkShortcutController">
|
||||||
|
|
@ -42,9 +43,8 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<property name="content">
|
<property name="content">
|
||||||
<object class="GtkBox">
|
<object class="AdwOverlaySplitView">
|
||||||
<property name="orientation">horizontal</property>
|
<property name="sidebar">
|
||||||
<child>
|
|
||||||
<object class="AdwPreferencesPage">
|
<object class="AdwPreferencesPage">
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="width-request">300</property>
|
<property name="width-request">300</property>
|
||||||
|
|
@ -151,17 +151,18 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
<child>
|
<property name="content">
|
||||||
<object class="LpPrintPreview" id="preview">
|
<object class="LpPrintPreview" id="preview">
|
||||||
<property name="valign">center</property>
|
<property name="vexpand">true</property>
|
||||||
<property name="halign">center</property>
|
<property name="hexpand">true</property>
|
||||||
<property name="css-name">lpprintpreview</property>
|
<property name="width-request">260</property>
|
||||||
|
<property name="height-request">260</property>
|
||||||
<binding name="print">
|
<binding name="print">
|
||||||
<constant>LpPrint</constant>
|
<constant>LpPrint</constant>
|
||||||
</binding>
|
</binding>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
</property>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,11 @@ row.property label.subtitle {
|
||||||
}
|
}
|
||||||
|
|
||||||
lpprintpreview {
|
lpprintpreview {
|
||||||
background-color: rgb(240, 240, 240);
|
background-color: #858585;
|
||||||
border-radius: 4px;
|
padding: 30px;
|
||||||
box-shadow: 0 0 14px 1px black;
|
}
|
||||||
|
|
||||||
|
lpprintpreviewpage {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
box-shadow: 0 0 14px 3px #666;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,64 +25,39 @@ use glib::Properties;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
mod imp {
|
mod imp_page {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Debug, Default, Properties)]
|
#[derive(Debug, Default)]
|
||||||
#[properties(wrapper_type = super::LpPrintPreview)]
|
pub struct LpPrintPreviewPage {}
|
||||||
pub struct LpPrintPreview {
|
|
||||||
#[property(get, set)]
|
|
||||||
print: OnceCell<LpPrint>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for LpPrintPreview {
|
impl ObjectSubclass for LpPrintPreviewPage {
|
||||||
const NAME: &'static str = "LpPrintPreview";
|
const NAME: &'static str = "LpPrintPreviewPage";
|
||||||
type Type = super::LpPrintPreview;
|
type Type = super::LpPrintPreviewPage;
|
||||||
type ParentType = gtk::Widget;
|
type ParentType = gtk::Widget;
|
||||||
|
|
||||||
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
klass.set_css_name("lpprintpreviewpage")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectImpl for LpPrintPreview {
|
impl ObjectImpl for LpPrintPreviewPage {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
self.obj().set_halign(gtk::Align::Center);
|
|
||||||
self.obj().set_valign(gtk::Align::Start);
|
|
||||||
self.obj().set_overflow(gtk::Overflow::Hidden);
|
self.obj().set_overflow(gtk::Overflow::Hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn properties() -> &'static [glib::ParamSpec] {
|
|
||||||
Self::derived_properties()
|
|
||||||
}
|
|
||||||
fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
|
||||||
self.derived_set_property(id, value, pspec)
|
|
||||||
}
|
|
||||||
fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
|
||||||
self.derived_property(id, pspec)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetImpl for LpPrintPreview {
|
impl WidgetImpl for LpPrintPreviewPage {
|
||||||
fn measure(&self, orientation: gtk::Orientation, _for_size: i32) -> (i32, i32, i32, i32) {
|
|
||||||
let (width, height) = self.display_paper_dimensions();
|
|
||||||
|
|
||||||
let size = match orientation {
|
|
||||||
gtk::Orientation::Horizontal => width,
|
|
||||||
_ => height,
|
|
||||||
};
|
|
||||||
|
|
||||||
(size, size, -1, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn snapshot(&self, snapshot: >k::Snapshot) {
|
fn snapshot(&self, snapshot: >k::Snapshot) {
|
||||||
let obj = self.obj();
|
|
||||||
|
|
||||||
snapshot.save();
|
snapshot.save();
|
||||||
|
|
||||||
let scale = obj.print().user_scale() * self.display_scale();
|
let scale = self.print().user_scale() * self.display_scale();
|
||||||
let margin_left = obj.print().effective_margin_left() * self.display_scale();
|
let margin_left = self.print().effective_margin_left() * self.display_scale();
|
||||||
let margin_top = obj.print().effective_margin_top() * self.display_scale();
|
let margin_top = self.print().effective_margin_top() * self.display_scale();
|
||||||
|
|
||||||
if let Some(texture) = self.obj().print().image().print_data(scale) {
|
if let Some(texture) = self.print().image().print_data(scale) {
|
||||||
let area = graphene::Rect::new(
|
let area = graphene::Rect::new(
|
||||||
margin_left as f32,
|
margin_left as f32,
|
||||||
margin_top as f32,
|
margin_top as f32,
|
||||||
|
|
@ -106,34 +81,108 @@ mod imp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LpPrintPreview {
|
impl LpPrintPreviewPage {
|
||||||
/// Returns scale factor from print pixel to preview size
|
fn preview(&self) -> super::LpPrintPreview {
|
||||||
fn display_scale(&self) -> f64 {
|
self.obj().parent().unwrap().downcast().unwrap()
|
||||||
let print = self.obj().print();
|
|
||||||
|
|
||||||
let height = print.page_setup().paper_height(gtk::Unit::Inch) * print.dpi();
|
|
||||||
let width = print.page_setup().paper_width(gtk::Unit::Inch) * print.dpi();
|
|
||||||
|
|
||||||
300. / f64::max(width, height)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns total preview size in pixels
|
fn print(&self) -> LpPrint {
|
||||||
fn display_paper_dimensions(&self) -> (i32, i32) {
|
self.preview().print()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_scale(&self) -> f64 {
|
||||||
|
let print = self.print();
|
||||||
|
let page_width = print.page_setup().paper_width(gtk::Unit::Inch) * print.dpi();
|
||||||
|
self.obj().width() as f64 / page_width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod imp {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Properties)]
|
||||||
|
#[properties(wrapper_type = super::LpPrintPreview)]
|
||||||
|
pub struct LpPrintPreview {
|
||||||
|
#[property(get, set)]
|
||||||
|
print: OnceCell<LpPrint>,
|
||||||
|
page: LpPrintPreviewPage,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::object_subclass]
|
||||||
|
impl ObjectSubclass for LpPrintPreview {
|
||||||
|
const NAME: &'static str = "LpPrintPreview";
|
||||||
|
type Type = super::LpPrintPreview;
|
||||||
|
type ParentType = gtk::Widget;
|
||||||
|
|
||||||
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
klass.set_css_name("lpprintpreview")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectImpl for LpPrintPreview {
|
||||||
|
fn constructed(&self) {
|
||||||
|
self.parent_constructed();
|
||||||
|
|
||||||
|
self.page.insert_after(&*self.obj(), gtk::Widget::NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn properties() -> &'static [glib::ParamSpec] {
|
||||||
|
Self::derived_properties()
|
||||||
|
}
|
||||||
|
fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
||||||
|
self.derived_set_property(id, value, pspec)
|
||||||
|
}
|
||||||
|
fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||||
|
self.derived_property(id, pspec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WidgetImpl for LpPrintPreview {
|
||||||
|
fn size_allocate(&self, width: i32, height: i32, baseline: i32) {
|
||||||
|
let (page_width, page_height) = self.aspect_preserving_size(width, height);
|
||||||
|
|
||||||
|
self.page.size_allocate(
|
||||||
|
&gdk::Rectangle::new(
|
||||||
|
(width - page_width) / 2,
|
||||||
|
(height - page_height) / 2,
|
||||||
|
page_width,
|
||||||
|
page_height,
|
||||||
|
),
|
||||||
|
baseline,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.page.queue_draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LpPrintPreview {
|
||||||
|
fn aspect_preserving_size(&self, for_width: i32, for_height: i32) -> (i32, i32) {
|
||||||
let print = self.obj().print();
|
let print = self.obj().print();
|
||||||
|
|
||||||
let height = print.page_setup().paper_height(gtk::Unit::Inch) * print.dpi();
|
let ratio = (print.page_setup().paper_width(gtk::Unit::Inch)
|
||||||
let width = print.page_setup().paper_width(gtk::Unit::Inch) * print.dpi();
|
/ print.page_setup().paper_height(gtk::Unit::Inch)) as f32;
|
||||||
|
|
||||||
let scale = self.display_scale();
|
if ratio > for_width as f32 / for_height as f32 {
|
||||||
|
(for_width, (for_width as f32 / ratio) as i32)
|
||||||
((width * scale) as i32, (height * scale) as i32)
|
} else {
|
||||||
|
((for_height as f32 * ratio) as i32, for_height)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct LpPrintPreview(ObjectSubclass<imp::LpPrintPreview>)
|
pub struct LpPrintPreviewPage(ObjectSubclass<imp_page::LpPrintPreviewPage>)
|
||||||
@extends gtk::Widget;
|
@extends gtk::Widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gtk::template_callbacks]
|
impl Default for LpPrintPreviewPage {
|
||||||
impl LpPrintPreview {}
|
fn default() -> Self {
|
||||||
|
glib::Object::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct LpPrintPreview(ObjectSubclass<imp::LpPrintPreview>)
|
||||||
|
@extends gtk::Widget;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue