The print dialog in the CHANGELOG and the widget catalogue
CI / build + test (push) Canceled after 0s
CI / cargo audit (push) Canceled after 0s

The commit that added `ltk::print` left both out. `CHANGELOG.md` gains its entry under Added, after `ltk::dirs`: what the dialog offers, how the app answers its requests for a preview, CUPS loaded at first use, the printers, jobs and default printer for a settings page, the print portal for an app in a Flatpak with `ltk::print::gtk` for a portal backend, zbus in the `wayland` feature, and only saving as PDF on Windows, Android and in a browser.
`docs/widgets.md` describes `print_dialog` among the pickers, after `file_chooser`, and links it from the table of contents: a component the app holds as it holds the file chooser, the preview the app renders on request, the job it delivers with `ltk::print::send`, and the builders that choose where it starts. Its example opens the dialog, answers its events and sends the PDF to a printer, and is compiled by `make doctest-md`.
This commit is contained in:
2026-11-01 22:53:46 +01:00
parent 45b8ddd483
commit 058a65546d
2 changed files with 48 additions and 1 deletions
+47 -1
View File
@@ -26,7 +26,7 @@ patterns built from these widgets, see [`docs/cookbook.md`](./cookbook.md).
- [Overlays and feedback](#overlays-and-feedback)
- [`spinner`](#spinner) · [`toast`](#toast) · [`tooltip`](#tooltip) · [`anchored`](#anchored) · [`combo`](#combo) · [`tabs`](#tabs) · [`notebook`](#notebook) · [`tab_strip`](#tab_strip) · [`dialog`](#dialog)
- [Pickers](#pickers)
- [`date_picker`](#date_picker) · [`time_picker`](#time_picker) · [`color_picker`](#color_picker) · [`file_chooser`](#file_chooser)
- [`date_picker`](#date_picker) · [`time_picker`](#time_picker) · [`color_picker`](#color_picker) · [`file_chooser`](#file_chooser) · [`print_dialog`](#print_dialog)
- [Layouts](#layouts)
- [`column`](#column) · [`row`](#row) · [`stack`](#stack) · [`grid`](#grid) · [`spacer`](#spacer)
@@ -1061,6 +1061,52 @@ fn update( &mut self, msg: Msg )
---
### `print_dialog`
Where and how to print, with a preview of the pages. Like the file chooser it is a component the app holds: `PrintDialog::new` makes it, its `view()` goes in the app's view, and its `PrintDialogMsg`s, which `wrap` makes the app's own, go to `update()`, which returns a `PrintEvent`. It lists the printers CUPS knows on its own through the app's `ChannelSender`, with "Save as PDF" after them, and offers the copies, the pages, the paper, the orientation, the margins, the scale, two-sided printing, colour and background graphics. The app renders the document itself: with `preview( true )` the dialog sends `PrintEvent::Preview( options )` whenever the layout changes, and the app answers with `PrintDialogMsg::previewed`, a `Preview` of pages rendered about `PREVIEW_WIDTH` pixels wide; `PrintEvent::Print( job )` says where and how once the user accepts, and `ltk::print::send` delivers the PDF to a printer or, in a Flatpak, to the print portal, whose own dialog the user saw instead. `options` starts from options kept from an earlier job, `printer` or `save_as_pdf` choose where it starts, `compact( true )` makes it a whole page for a phone, and `take_focus_request` gives the field to focus.
**When**: any app that prints, instead of a dialog of its own.
```rust,no_run
# use ltk::{ ChannelSender, Element };
# use ltk::print::{ Destination, PrintDialog, PrintDialogMsg, PrintEvent, PrintOptions };
# #[ derive( Clone ) ] enum Msg { Print, Dialog( PrintDialogMsg ), Sent( Result<(), String> ) }
# struct App { print: Option<PrintDialog<Msg>>, sender: ChannelSender<Msg> }
# impl App {
# fn render( &self, _options: &PrintOptions ) -> Vec<u8> { Vec::new() }
fn update( &mut self, msg: Msg )
{
match msg
{
Msg::Print => self.print = Some( PrintDialog::new( &self.sender, Msg::Dialog, "Report" ).preview( true ) ),
Msg::Dialog( msg ) =>
{
let Some( dialog ) = &mut self.print else { return };
match dialog.update( msg )
{
Some( PrintEvent::Preview( _options ) ) => { /* render the pages, then send Msg::Dialog( PrintDialogMsg::previewed( .. ) ) */ }
Some( PrintEvent::Print( job ) ) =>
{
self.print = None;
if job.destination == Destination::Pdf { return; /* ask for a file with a FileChooser */ }
let pdf = self.render( &job.options );
ltk::print::send( &job.destination, &job.title, &job.options, pdf, &self.sender, Msg::Sent );
}
Some( PrintEvent::Cancelled ) => self.print = None,
None => {}
}
}
Msg::Sent( _result ) => {}
}
}
# fn view( &self ) -> Element<Msg> { self.print.as_ref().map( PrintDialog::view ).unwrap() }
# }
```
**See also**: [`ltk::print`](../src/print/mod.rs) for the printers, their jobs and the default printer, as a settings page shows them, and `ltk::print::gtk` for the portal's print settings.
---
## Layouts
### `column`