2023-04-19 20:02:01 +02:00
|
|
|
// Copyright (c) 2023 Sophie Herold
|
|
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
//
|
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
2023-04-02 01:39:23 +02:00
|
|
|
//! Print preview widget that shows a fake page with the image on it
|
|
|
|
|
|
2023-12-25 20:18:26 +01:00
|
|
|
use std::cell::RefCell;
|
|
|
|
|
|
2023-04-02 01:39:23 +02:00
|
|
|
use adw::subclass::prelude::*;
|
|
|
|
|
use glib::Properties;
|
|
|
|
|
use gtk::prelude::*;
|
|
|
|
|
|
2023-12-06 23:45:02 +01:00
|
|
|
use crate::deps::*;
|
|
|
|
|
use crate::widgets::LpPrint;
|
|
|
|
|
|
2023-12-25 20:18:26 +01:00
|
|
|
use super::image;
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
mod imp_page {
|
2023-04-02 01:39:23 +02:00
|
|
|
use super::*;
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
#[derive(Debug, Default)]
|
|
|
|
|
pub struct LpPrintPreviewPage {}
|
2023-04-02 01:39:23 +02:00
|
|
|
|
|
|
|
|
#[glib::object_subclass]
|
2023-06-26 15:35:16 +02:00
|
|
|
impl ObjectSubclass for LpPrintPreviewPage {
|
|
|
|
|
const NAME: &'static str = "LpPrintPreviewPage";
|
|
|
|
|
type Type = super::LpPrintPreviewPage;
|
2023-04-02 01:39:23 +02:00
|
|
|
type ParentType = gtk::Widget;
|
2023-06-26 15:35:16 +02:00
|
|
|
|
|
|
|
|
fn class_init(klass: &mut Self::Class) {
|
|
|
|
|
klass.set_css_name("lpprintpreviewpage")
|
|
|
|
|
}
|
2023-04-02 01:39:23 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
impl ObjectImpl for LpPrintPreviewPage {
|
2023-04-02 01:39:23 +02:00
|
|
|
fn constructed(&self) {
|
|
|
|
|
self.parent_constructed();
|
|
|
|
|
self.obj().set_overflow(gtk::Overflow::Hidden);
|
|
|
|
|
}
|
2023-12-25 20:18:26 +01:00
|
|
|
|
|
|
|
|
fn dispose(&self) {
|
|
|
|
|
self.obj().first_child().unwrap().unparent();
|
|
|
|
|
}
|
2023-04-02 01:39:23 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
impl WidgetImpl for LpPrintPreviewPage {
|
2023-12-25 20:18:26 +01:00
|
|
|
fn size_allocate(&self, _width: i32, _height: i32, _baseline: i32) {
|
2023-06-26 15:35:16 +02:00
|
|
|
let margin_left = self.print().effective_margin_left() * self.display_scale();
|
|
|
|
|
let margin_top = self.print().effective_margin_top() * self.display_scale();
|
2023-12-25 20:18:26 +01:00
|
|
|
let width = self.print().user_width() * self.display_scale();
|
|
|
|
|
let height = self.print().user_height() * self.display_scale();
|
|
|
|
|
|
|
|
|
|
let image = self.print().image();
|
|
|
|
|
|
|
|
|
|
image.allocate(
|
|
|
|
|
width as i32,
|
|
|
|
|
height as i32,
|
|
|
|
|
-1,
|
|
|
|
|
Some(
|
|
|
|
|
gsk::Transform::new()
|
|
|
|
|
.translate(&graphene::Point::new(margin_left as f32, margin_top as f32)),
|
|
|
|
|
),
|
|
|
|
|
);
|
2023-04-02 01:39:23 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
impl LpPrintPreviewPage {
|
2023-12-25 20:18:26 +01:00
|
|
|
pub(super) fn preview(&self) -> super::LpPrintPreview {
|
2023-06-26 15:35:16 +02:00
|
|
|
self.obj().parent().unwrap().downcast().unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn print(&self) -> LpPrint {
|
|
|
|
|
self.preview().print()
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-02 01:39:23 +02:00
|
|
|
fn display_scale(&self) -> f64 {
|
2023-06-26 15:35:16 +02:00
|
|
|
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 {
|
2023-12-25 20:18:26 +01:00
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Default, Properties)]
|
|
|
|
|
#[properties(wrapper_type = super::LpPrintPreview)]
|
|
|
|
|
pub struct LpPrintPreview {
|
2023-12-25 20:18:26 +01:00
|
|
|
#[property(type = LpPrint, get, set = Self::set_print)]
|
|
|
|
|
print: RefCell<Option<LpPrint>>,
|
2023-06-26 15:35:16 +02:00
|
|
|
page: LpPrintPreviewPage,
|
|
|
|
|
}
|
2023-04-02 01:39:23 +02:00
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
#[glib::object_subclass]
|
|
|
|
|
impl ObjectSubclass for LpPrintPreview {
|
|
|
|
|
const NAME: &'static str = "LpPrintPreview";
|
|
|
|
|
type Type = super::LpPrintPreview;
|
|
|
|
|
type ParentType = gtk::Widget;
|
2023-04-02 01:39:23 +02:00
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
fn class_init(klass: &mut Self::Class) {
|
|
|
|
|
klass.set_css_name("lpprintpreview")
|
2023-04-02 01:39:23 +02:00
|
|
|
}
|
2023-06-26 15:35:16 +02:00
|
|
|
}
|
2023-04-02 01:39:23 +02:00
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
impl ObjectImpl for LpPrintPreview {
|
|
|
|
|
fn constructed(&self) {
|
|
|
|
|
self.parent_constructed();
|
2023-04-02 01:39:23 +02:00
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
self.page.insert_after(&*self.obj(), gtk::Widget::NONE);
|
|
|
|
|
}
|
2023-04-02 01:39:23 +02:00
|
|
|
|
2023-12-25 20:18:26 +01:00
|
|
|
fn dispose(&self) {
|
|
|
|
|
self.page.unparent();
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-02 01:39:23 +02:00
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
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,
|
|
|
|
|
);
|
|
|
|
|
|
2023-12-25 20:18:26 +01:00
|
|
|
self.page.queue_resize();
|
2023-06-26 15:35:16 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl LpPrintPreview {
|
2023-12-25 20:18:26 +01:00
|
|
|
fn set_print(&self, print: LpPrint) {
|
|
|
|
|
let page = self.page.clone();
|
|
|
|
|
print.connect_image_notify(move |_| {
|
|
|
|
|
page.init();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
self.print.replace(Some(print));
|
|
|
|
|
self.obj().notify_print();
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
fn aspect_preserving_size(&self, for_width: i32, for_height: i32) -> (i32, i32) {
|
|
|
|
|
let print = self.obj().print();
|
|
|
|
|
|
|
|
|
|
let ratio = (print.page_setup().paper_width(gtk::Unit::Inch)
|
|
|
|
|
/ print.page_setup().paper_height(gtk::Unit::Inch)) as f32;
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
2023-04-02 01:39:23 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
glib::wrapper! {
|
2023-06-26 15:35:16 +02:00
|
|
|
pub struct LpPrintPreviewPage(ObjectSubclass<imp_page::LpPrintPreviewPage>)
|
2023-04-02 01:39:23 +02:00
|
|
|
@extends gtk::Widget;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
impl Default for LpPrintPreviewPage {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
glib::Object::new()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-25 20:18:26 +01:00
|
|
|
impl LpPrintPreviewPage {
|
|
|
|
|
fn init(&self) {
|
|
|
|
|
let imp = self.imp();
|
|
|
|
|
let image = imp.preview().print().image();
|
|
|
|
|
|
|
|
|
|
image.set_sensitive(false);
|
|
|
|
|
image.set_parent(self);
|
|
|
|
|
image.set_fit_mode(image::FitMode::LargeFit);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-26 15:35:16 +02:00
|
|
|
glib::wrapper! {
|
|
|
|
|
pub struct LpPrintPreview(ObjectSubclass<imp::LpPrintPreview>)
|
|
|
|
|
@extends gtk::Widget;
|
|
|
|
|
}
|