Skip to content

Commit

Permalink
Add support to print controls and print preview dialog
Browse files Browse the repository at this point in the history
Fixes #969
  • Loading branch information
cwensley committed Oct 17, 2021
1 parent 623ff49 commit c681c15
Show file tree
Hide file tree
Showing 37 changed files with 1,202 additions and 211 deletions.
2 changes: 1 addition & 1 deletion src/Eto.Gtk/Forms/Controls/GridHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public override void AttachEvent(string id)
var columnIndex = GetColumnOfItem(e.Column);
var item = GetItem(e.Path);
var column = columnIndex == -1 ? null : Widget.Columns[columnIndex];
Callback.OnCellClick(Widget, new GridCellMouseEventArgs(column, rowIndex, columnIndex, item, Mouse.Buttons, Keyboard.Modifiers, PointFromScreen(Mouse.Position)));
Callback.OnCellDoubleClick(Widget, new GridCellMouseEventArgs(column, rowIndex, columnIndex, item, Mouse.Buttons, Keyboard.Modifiers, PointFromScreen(Mouse.Position)));
};
break;
case Grid.SelectionChangedEvent:
Expand Down
5 changes: 5 additions & 0 deletions src/Eto.Gtk/Forms/GtkControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -996,5 +996,10 @@ public virtual void InvalidateMeasure()
Widget.VisualParent?.GetGtkControlHandler()?.InvalidateMeasure();
}
}

public void Print()
{
// ContainerControl.Print
}
}
}
52 changes: 25 additions & 27 deletions src/Eto.Gtk/Forms/Printing/PrintDialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ public class PrintDialogHandler : WidgetHandler<Gtk.PrintUnixDialog, PrintDialog
{
PrintSettings settings;

public PrintDialogHandler()
{
AllowPageRange = true;
}

public PrintDocument Document { get; set; }

public class CustomOptions : Gtk.VBox
Expand All @@ -27,15 +22,16 @@ public CustomOptions()

public DialogResult ShowDialog(Window parent)
{
var parentWindow = parent != null ? (Gtk.Window)parent.ControlObject : null;
var parentWindow = parent?.ControlObject as Gtk.Window;
Control = new Gtk.PrintUnixDialog(string.Empty, parentWindow);

if (parent != null)
if (parentWindow != null)
{
Control.TransientFor = ((Gtk.Window)parent.ControlObject);
Control.TransientFor = parentWindow;
Control.Modal = true;
}


const Gtk.PrintCapabilities caps = Gtk.PrintCapabilities.Preview
| Gtk.PrintCapabilities.Collate
| Gtk.PrintCapabilities.GeneratePdf
Expand All @@ -59,37 +55,39 @@ public DialogResult ShowDialog(Window parent)
NativeMethods.gtk_print_unix_dialog_set_embed_page_setup(Control.Handle, true);

Control.ManualCapabilities = caps;
Control.ShowAll ();
var response = (Gtk.ResponseType)Control.Run ();
Control.Hide ();
Control.ShowAll();
var response = (Gtk.ResponseType)Control.Run();
Control.Hide();
Control.Unrealize();

printSettingsHandler.Set(Control.PrintSettings, Control.PageSetup, customOptions.SelectionOnly.Active);
if (response == Gtk.ResponseType.Apply) {
if (Document != null)
Document.PrintSettings = PrintSettings;

if (response == Gtk.ResponseType.Apply)
{
printSettingsHandler.ShowPreview = true;
(Document?.Handler as PrintDocumentHandler)?.Print(parentWindow);
return DialogResult.Ok;
}
if (response == Gtk.ResponseType.Ok)
{
(Document?.Handler as PrintDocumentHandler)?.Print(parentWindow);
}

return response.ToEto ();
return response.ToEto();
}
public PrintSettings PrintSettings {
get {
if (settings == null) settings = new PrintSettings();
return settings;
}
set {
settings = value;
}

public PrintSettings PrintSettings
{
get => settings ?? (settings = new PrintSettings());
set => settings = value;
}

// not supported in gtk
public bool AllowPageRange {
get; set;
}
public bool AllowPageRange { get; set; } = true;

public bool AllowSelection {
get; set;
}
public bool AllowSelection { get; set; }
}
}

124 changes: 99 additions & 25 deletions src/Eto.Gtk/Forms/Printing/PrintDocumentHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,126 @@ namespace Eto.GtkSharp.Forms.Printing
{
public class PrintDocumentHandler : WidgetHandler<Gtk.PrintOperation, PrintDocument, PrintDocument.ICallback>, PrintDocument.IHandler
{
PrintSettings settings;
PrintSettings _settings;
Control _control;
SizeF _preferredSize;
Gtk.Widget _oldParent;
#if GTK3
Gtk.OffscreenWindow _offscreenWindow;
#endif

public PrintDocumentHandler()
{
Control = new Gtk.PrintOperation();
Control.BeginPrint += Control_BeginPrint;
Control.EndPrint += Control_EndPrint;
Control.DrawPage += Control_DrawPage;
}

public void Print()
private void Control_EndPrint(object o, Gtk.EndPrintArgs args)
{
Callback.OnPrinted(Widget, EventArgs.Empty);
if (_oldParent != null && _control != null)
{
var gtkWidget = _control.GetContainerWidget();
gtkWidget.Parent = _oldParent;
_oldParent = null;
}
}

private void Control_BeginPrint(object o, Gtk.BeginPrintArgs args)
{
if (_control != null && PageCount == -1)
{
var paperHeight = args.Context.Height;
var paperWidth = args.Context.Width;

_preferredSize = _control.GetPreferredSize();
#if GTK3
// to draw the widget using Cairo, we need to use an offscreen window
var gtkWidget = _control.GetContainerWidget();
_oldParent = gtkWidget.Parent;
_offscreenWindow = new Gtk.OffscreenWindow();
_offscreenWindow.Child = gtkWidget;

_offscreenWindow.SetSizeRequest((int)Math.Max(_preferredSize.Width, paperWidth), (int)Math.Max(_preferredSize.Height, paperHeight));
_offscreenWindow.ShowAll();
#endif

PageCount = (int)Math.Ceiling(_preferredSize.Height / paperHeight);
}
Callback.OnPrinting(Widget, EventArgs.Empty);
}

internal void Print(Gtk.Window parentWindow)
{
var settingsHandler = (PrintSettingsHandler)PrintSettings.Handler;

Control.PrintSettings = settingsHandler.Control;
if (settingsHandler.ShowPreview)
Control.Run(Gtk.PrintOperationAction.Preview, null);
{
Control.Run(Gtk.PrintOperationAction.Preview, parentWindow);
}
else
Control.Run(Gtk.PrintOperationAction.Print, null);
{
Control.Run(Gtk.PrintOperationAction.PrintDialog, parentWindow);
}
}

public void Create()
{
}

public void Create(Control control)
{
_control = control;
}

public void Print() => Print(null);

public override void AttachEvent(string id)
{
switch (id)
{
case PrintDocument.PrintingEvent:
Control.BeginPrint += (o, args) => Callback.OnPrinting(Widget, EventArgs.Empty);
break;
case PrintDocument.PrintedEvent:
Control.EndPrint += (o, args) => Callback.OnPrinted(Widget, EventArgs.Empty);
break;

case PrintDocument.PrintPageEvent:
Control.DrawPage += (o, args) =>
{
using (var graphics = new Graphics(new GraphicsHandler(args.Context.CairoContext, args.Context.CreatePangoContext())))
{
var width = args.Context.Width; //.PageSetup.GetPageWidth(Gtk.Unit.Points);
var height = args.Context.Height; //.PageSetup.GetPageHeight(Gtk.Unit.Points);
var e = new PrintPageEventArgs(graphics, new SizeF((float)width, (float)height), args.PageNr);
Callback.OnPrintPage(Widget, e);
}
};
// handled intrinsically
break;
default:
base.AttachEvent(id);
break;
}
}

private void Control_DrawPage(object o, Gtk.DrawPageArgs args)
{
var width = args.Context.Width;
var height = args.Context.Height;
var pageNumber = args.PageNr;

var context = args.Context.CairoContext;

if (_control != null)
{
context.Save();
context.Rectangle(new Cairo.Rectangle(0, 0, width, height));
context.Clip();
var ctl = _control.GetContainerWidget();
context.Translate(0, -pageNumber * height);
#if !GTK2
ctl.Draw(context);
#endif
context.Restore();
}

using (var graphics = new Graphics(new GraphicsHandler(context, args.Context.CreatePangoContext())))
{
var e = new PrintPageEventArgs(graphics, new SizeF((float)width, (float)height), pageNumber);
Callback.OnPrintPage(Widget, e);
}
}

public string Name
{
get { return Control.JobName; }
Expand All @@ -63,15 +137,15 @@ public PrintSettings PrintSettings
{
get
{
if (settings == null)
settings = Control.PrintSettings.ToEto(Control.DefaultPageSetup, false);
return settings;
if (_settings == null)
_settings = Control.PrintSettings.ToEto(Control.DefaultPageSetup, false);
return _settings;
}
set
{
settings = value;
Control.DefaultPageSetup = settings.ToGtkPageSetup();
Control.PrintSettings = settings.ToGtkPrintSettings();
_settings = value;
Control.DefaultPageSetup = _settings.ToGtkPageSetup();
Control.PrintSettings = _settings.ToGtkPrintSettings();
}
}

Expand Down
32 changes: 32 additions & 0 deletions src/Eto.Gtk/Forms/Printing/PrintPreviewDialogHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Eto.Forms;

namespace Eto.GtkSharp.Forms.Printing
{
public class PrintPreviewDialogHandler : WidgetHandler<object, PrintPreviewDialog>, PrintPreviewDialog.IHandler
{
PrintSettings settings;

public PrintDocument Document { get; set; }

public DialogResult ShowDialog(Window parent)
{
var parentWindow = parent?.ControlObject as Gtk.Window;

var printSettingsHandler = (PrintSettingsHandler)PrintSettings.Handler;

Document.PrintSettings = PrintSettings;

printSettingsHandler.ShowPreview = true;
((PrintDocumentHandler)Document.Handler).Print(parentWindow);
return DialogResult.Ok;
}

public PrintSettings PrintSettings
{
get => settings ?? (settings = new PrintSettings());
set => settings = value;
}

}
}

1 change: 1 addition & 0 deletions src/Eto.Gtk/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ public static void AddTo(Eto.Platform p)

// Forms.Printing
p.Add<PrintDialog.IHandler>(() => new PrintDialogHandler());
p.Add<PrintPreviewDialog.IHandler>(() => new PrintPreviewDialogHandler());
p.Add<PrintDocument.IHandler>(() => new PrintDocumentHandler());
p.Add<PrintSettings.IHandler>(() => new PrintSettingsHandler());

Expand Down
1 change: 1 addition & 0 deletions src/Eto.Mac/Eto.XamMac2.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<DefineConstants>$(DefineConstants);OSX;DESKTOP;XAMMAC;XAMMAC2;UNIFIED</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>build\*</DefaultItemExcludes>
<NoWarn>CA1416</NoWarn>
</PropertyGroup>

<PropertyGroup>
Expand Down
19 changes: 10 additions & 9 deletions src/Eto.Mac/Forms/MacView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,12 @@ public virtual bool Visible
}
}
}

public void Print()
{
PrintSettingsHandler.SetDefaults(NSPrintInfo.SharedPrintInfo);
ContainerControl.Print(ContainerControl);
}

public virtual Cursor CurrentCursor
{
Expand Down Expand Up @@ -1069,15 +1075,6 @@ public string ToolTip
set { ContentControl.ToolTip = value ?? string.Empty; }
}

public void Print(PrintSettings settings)
{
var op = NSPrintOperation.FromView(EventControl);
if (settings != null)
op.PrintInfo = ((PrintSettingsHandler)settings.Handler).Control;
op.ShowsPrintPanel = false;
op.RunOperation();
}

public virtual void OnPreLoad(EventArgs e)
{
}
Expand All @@ -1089,6 +1086,10 @@ public virtual void OnLoad(EventArgs e)
// adding dynamically or loading without a parent (e.g. embedding into a native app)
AsyncQueue.Add(FireOnShown);
}
if (Widget.IsAttached)
{
SetAlignmentFrameSize(GetPreferredSize(SizeF.PositiveInfinity).ToNS());
}
}

public virtual void OnLoadComplete(EventArgs e)
Expand Down
2 changes: 1 addition & 1 deletion src/Eto.Mac/Forms/Printing/PrintDialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

namespace Eto.Mac.Forms.Printing
{
public class PrintDialogHandler : WidgetHandler<NSPrintPanel, PrintDialog>, PrintDialog.IHandler
public class PrintDialogHandler : WidgetHandler<NSPrintPanel, CommonDialog>, PrintDialog.IHandler, PrintPreviewDialog.IHandler
{
PrintSettings settings;

Expand Down
Loading

0 comments on commit c681c15

Please sign in to comment.