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
|
|
@ -25,64 +25,39 @@ use glib::Properties;
|
|||
use gtk::prelude::*;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
mod imp {
|
||||
mod imp_page {
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, Properties)]
|
||||
#[properties(wrapper_type = super::LpPrintPreview)]
|
||||
pub struct LpPrintPreview {
|
||||
#[property(get, set)]
|
||||
print: OnceCell<LpPrint>,
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct LpPrintPreviewPage {}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for LpPrintPreview {
|
||||
const NAME: &'static str = "LpPrintPreview";
|
||||
type Type = super::LpPrintPreview;
|
||||
impl ObjectSubclass for LpPrintPreviewPage {
|
||||
const NAME: &'static str = "LpPrintPreviewPage";
|
||||
type Type = super::LpPrintPreviewPage;
|
||||
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) {
|
||||
self.parent_constructed();
|
||||
self.obj().set_halign(gtk::Align::Center);
|
||||
self.obj().set_valign(gtk::Align::Start);
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
impl WidgetImpl for LpPrintPreviewPage {
|
||||
fn snapshot(&self, snapshot: >k::Snapshot) {
|
||||
let obj = self.obj();
|
||||
|
||||
snapshot.save();
|
||||
|
||||
let scale = obj.print().user_scale() * self.display_scale();
|
||||
let margin_left = obj.print().effective_margin_left() * self.display_scale();
|
||||
let margin_top = obj.print().effective_margin_top() * self.display_scale();
|
||||
let scale = self.print().user_scale() * self.display_scale();
|
||||
let margin_left = self.print().effective_margin_left() * 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(
|
||||
margin_left as f32,
|
||||
margin_top as f32,
|
||||
|
|
@ -106,34 +81,108 @@ mod imp {
|
|||
}
|
||||
}
|
||||
|
||||
impl LpPrintPreview {
|
||||
/// Returns scale factor from print pixel to preview size
|
||||
fn display_scale(&self) -> f64 {
|
||||
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)
|
||||
impl LpPrintPreviewPage {
|
||||
fn preview(&self) -> super::LpPrintPreview {
|
||||
self.obj().parent().unwrap().downcast().unwrap()
|
||||
}
|
||||
|
||||
/// Returns total preview size in pixels
|
||||
fn display_paper_dimensions(&self) -> (i32, i32) {
|
||||
fn print(&self) -> LpPrint {
|
||||
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 height = print.page_setup().paper_height(gtk::Unit::Inch) * print.dpi();
|
||||
let width = print.page_setup().paper_width(gtk::Unit::Inch) * print.dpi();
|
||||
let ratio = (print.page_setup().paper_width(gtk::Unit::Inch)
|
||||
/ print.page_setup().paper_height(gtk::Unit::Inch)) as f32;
|
||||
|
||||
let scale = self.display_scale();
|
||||
|
||||
((width * scale) as i32, (height * scale) as i32)
|
||||
if ratio > for_width as f32 / for_height as f32 {
|
||||
(for_width, (for_width as f32 / ratio) as i32)
|
||||
} else {
|
||||
((for_height as f32 * ratio) as i32, for_height)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
glib::wrapper! {
|
||||
pub struct LpPrintPreview(ObjectSubclass<imp::LpPrintPreview>)
|
||||
pub struct LpPrintPreviewPage(ObjectSubclass<imp_page::LpPrintPreviewPage>)
|
||||
@extends gtk::Widget;
|
||||
}
|
||||
|
||||
#[gtk::template_callbacks]
|
||||
impl LpPrintPreview {}
|
||||
impl Default for LpPrintPreviewPage {
|
||||
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