-
Notifications
You must be signed in to change notification settings - Fork 148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Windows support #121
Add Windows support #121
Conversation
Adds support for printing PDFs in react-native-windows. Updates the documentation.
Also makes the reference to react-native-print relative, so that the current version of the code can be tested.
windows/RNPrint/RNPrint.h
Outdated
const std::string Name = "RNPrint"; | ||
|
||
// Default name for the print job. | ||
inline static const std::string defaultJobName = "Document"; | ||
|
||
// Name for the XAML Canvas to add preview folders to. | ||
inline static const std::string RNPrintCanvasName = "RNPrintCanvas"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these can be constexpr
instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change them to char[]
as well, so that they can be constexpr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::string can be constexpr with c++20, or you can use string_view in C++17. In general try avoiding C style character strings/arrays
windows/RNPrint/RNPrint.h
Outdated
winrt::event_token printToken; | ||
|
||
REACT_INIT(RNPrint_Init) | ||
void RNPrint_Init(ReactContext const& context) noexcept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: spacing
windows/RNPrint/RNPrint.h
Outdated
} | ||
|
||
// Generates a XAML page asynchronously. | ||
concurrency::task<std::optional<xaml::UIElement> > GeneratePageAsync(PdfDocument pdfDocument, int pageNumber, PrintPageDescription pageDescription) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: you shouldn't need the space between > > anymore, I think? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
muscle memory from times past :)
windows/RNPrint/RNPrint.h
Outdated
float leftMargin = pageDescription.ImageableRect.X; | ||
float topMargin = pageDescription.ImageableRect.Y; | ||
float printableWidth = pageDescription.ImageableRect.Width; | ||
float printableHeight = pageDescription.ImageableRect.Height; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make these const
windows/RNPrint/RNPrint.h
Outdated
std::optional<xaml::UIElement> result = page; | ||
return result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return std::optionalxaml::UIElement(page);
or even more easily return page
windows/RNPrint/RNPrint.h
Outdated
[=](auto const& sender, GetPreviewPageEventArgs const& args) -> void | ||
{ | ||
auto printDocArg = sender.as<PrintDocument>(); | ||
int pageNumber = args.PageNumber(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
windows/RNPrint/RNPrint.h
Outdated
|
||
xaml::FrameworkElement root{ nullptr }; | ||
|
||
auto window = xaml::Window::Current(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this means this module won't work from xaml islands (which might be an ok compromise).
Another way to do this would be to fall back to use XamlUIService.XamlRoot if Window::Current is null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will include the suggested workaround.
Is there a sample that uses xaml islands with react-native-windows that I could take a look into?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaimecbernardo thanks! we don't have any modules that do so today since they mostly seem to work and not require access to something like Window::Current, but we do have code in the react-native-windows repo today that deals with this. See usages of XamlUIService.XamlRoot() and search for "isxamlisland" or something like that, we have a helper in the repo for it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PrintDocument printDoc = nullptr; | ||
IPrintDocumentSource printDocSource; | ||
int numberOfPages = 0; | ||
std::map<int, std::optional<xaml::UIElement>> pageCollection; // references to the xaml pages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it doesn't seem like you need this to be a map, you can just use std::vector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can be generated out of order and a map also would support a future feature to allow page range printing.
I think a map works better here.
Using a map also follows the Windows Universal Samples code for the Printing API more closely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree that they can be generated out of order, but you are capturing the index i in the lambda, so maybe you can use that? not a big concern here, just looking to simplify since std::map is big and clunky
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also the part of the when_all
later on which wants to send it to the printer in the right order.
Since we are generating a XAML element for each member in the collection, the std::map
overhead shouldn't have much impact in comparison.
The collection also isn't expected to end up having many members, since it's one per page.
windows/RNPrint/RNPrint.h
Outdated
if (options.find("html") != options.end()) | ||
printOptions.html = options["html"].AsString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid brace-less if
statements whenever possible (here and other places)
@@ -0,0 +1,402 @@ | |||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file is getting pretty large :) (github wouldn't show me the diff)
Can you break it up into a header and a source?
windows/RNPrint/RNPrint.h
Outdated
{ | ||
cleanUp(); | ||
std::stringstream errorCode; | ||
errorCode << "0x" << std::hex << action.ErrorCode() << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
undo the std::hex at the end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean the std::endl
?
I've used this code as a reference:
https://github.com/microsoft/react-native-windows-samples/blob/c1fe1ad0395d905c790b97edde76155efa9cced9/samples/NativeModuleSample/cppwinrt/windows/NativeModuleSample/AsyncMethodExamples.h#L68
But now that I think about it, that std::endl
might not make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a bug in the RNW code too :) basically std::hex changes state of the cout object, so any ints that come afterwards will be formatted as hex. AFAICT, endl only inserts a newline and doesn't reset the formatting options, so if someone prints a number to cout before anyone does << std::hex, it will show up in decimal, but if someone does it after this code runs, it will print as hex. Therefore it is unpredictable and we should reset to the default at the end of the line (<< std::dec << std::endl instead of std::endl)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. SGTM :)
Hi @asklar. |
👋 Hi @christopherdro! @jaimecbernardo @asklar and myself are part of the team at Microsoft working on React Native for Windows. What do we need to do to get this PR pulled in? |
Thank you for the PR everyone! I’ll have some free time next week during thanksgiving break to take a closer look. |
On Windows, `react-native-print` needs an element in the visual tree to add the printable pages to. | ||
It will look for a XAML `Canvas` named `RNPrintCanvas` and use it. | ||
This needs to be added to the XAML tree of the screens where `react-native-print` is used. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonthysell I wonder if we should bake logic into autolinking so that modules can check that certain conditions are met before they get autolinked, e.g. that there is this element. Or at least give a chance for modules to print out warnings / instructions of this kind.
Filed microsoft/react-native-windows#6553
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-authored-by: Alexander Sklar <asklar@microsoft.com>
Adds support for react-native-windows.
Implements PDF printing.
Updates the example for react-native 0.63 and adds the windows platform to it.
Updates the docs.
Adds a test to the sample and uses it for automatic CI for Windows.