mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 05:57:00 -04:00
Added option to disable spacing between printed cards
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1646 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -152,6 +152,13 @@ IMPLEMENT_REFLECTION_NO_SCRIPT(StyleSheetSettings) {
|
|||||||
REFLECT(card_spellcheck_enabled);
|
REFLECT(card_spellcheck_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Printing
|
||||||
|
|
||||||
|
IMPLEMENT_REFLECTION_ENUM(PageLayoutType) {
|
||||||
|
VALUE_N("no space", LAYOUT_NO_SPACE);
|
||||||
|
VALUE_N("equal space", LAYOUT_EQUAL_SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Settings
|
// ----------------------------------------------------------------------------- : Settings
|
||||||
|
|
||||||
Settings settings;
|
Settings settings;
|
||||||
@@ -166,6 +173,7 @@ Settings::Settings()
|
|||||||
, symbol_grid_size (30)
|
, symbol_grid_size (30)
|
||||||
, symbol_grid (true)
|
, symbol_grid (true)
|
||||||
, symbol_grid_snap (false)
|
, symbol_grid_snap (false)
|
||||||
|
, print_layout (LAYOUT_NO_SPACE)
|
||||||
#if USE_OLD_STYLE_UPDATE_CHECKER
|
#if USE_OLD_STYLE_UPDATE_CHECKER
|
||||||
, updates_url (_("http://magicseteditor.sourceforge.net/updates"))
|
, updates_url (_("http://magicseteditor.sourceforge.net/updates"))
|
||||||
#endif
|
#endif
|
||||||
@@ -253,6 +261,7 @@ IMPLEMENT_REFLECTION_NO_SCRIPT(Settings) {
|
|||||||
REFLECT(symbol_grid);
|
REFLECT(symbol_grid);
|
||||||
REFLECT(symbol_grid_snap);
|
REFLECT(symbol_grid_snap);
|
||||||
REFLECT(default_game);
|
REFLECT(default_game);
|
||||||
|
REFLECT(print_layout);
|
||||||
REFLECT(apprentice_location);
|
REFLECT(apprentice_location);
|
||||||
#if USE_OLD_STYLE_UPDATE_CHECKER
|
#if USE_OLD_STYLE_UPDATE_CHECKER
|
||||||
REFLECT(updates_url);
|
REFLECT(updates_url);
|
||||||
|
|||||||
@@ -112,6 +112,14 @@ class StyleSheetSettings : public IntrusivePtrBase<StyleSheetSettings> {
|
|||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Printing settings
|
||||||
|
|
||||||
|
enum PageLayoutType
|
||||||
|
{ LAYOUT_NO_SPACE
|
||||||
|
, LAYOUT_EQUAL_SPACE
|
||||||
|
//, LAYOUT_CUSTOM
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Settings
|
// ----------------------------------------------------------------------------- : Settings
|
||||||
|
|
||||||
/// Class that holds MSE settings.
|
/// Class that holds MSE settings.
|
||||||
@@ -178,6 +186,10 @@ class Settings {
|
|||||||
/// Get the options for an export template
|
/// Get the options for an export template
|
||||||
IndexMap<FieldP,ValueP>& exportOptionsFor(const ExportTemplate& export_template);
|
IndexMap<FieldP,ValueP>& exportOptionsFor(const ExportTemplate& export_template);
|
||||||
|
|
||||||
|
// --------------------------------------------------- : Printing
|
||||||
|
|
||||||
|
PageLayoutType print_layout;
|
||||||
|
|
||||||
// --------------------------------------------------- : Special game stuff
|
// --------------------------------------------------- : Special game stuff
|
||||||
String apprentice_location;
|
String apprentice_location;
|
||||||
|
|
||||||
|
|||||||
+77
-144
@@ -19,100 +19,6 @@
|
|||||||
DECLARE_TYPEOF_COLLECTION(CardP);
|
DECLARE_TYPEOF_COLLECTION(CardP);
|
||||||
DECLARE_POINTER_TYPE(PageLayout);
|
DECLARE_POINTER_TYPE(PageLayout);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Buffering DC
|
|
||||||
|
|
||||||
/// MemoryDC that buffers calls to write text
|
|
||||||
/** The printer device doesn't support alpha channels (at least not in wxMSW)
|
|
||||||
* This would result in black backgrounds where symbols should be transparent
|
|
||||||
* Our solution is:
|
|
||||||
* 1. Write all bitmaps to a buffer DC, initially white
|
|
||||||
* 2. When drawing with alpha: blend with the buffer
|
|
||||||
* 3. When drawing text: buffer the call
|
|
||||||
* 4. Draw the buffer image to the device
|
|
||||||
* 5. Replay the buffered text draw calls
|
|
||||||
* To simplify things this class itself is a fullblown DC, only text calls are buffered for later
|
|
||||||
* Actually buffering text separatly would not be necessary at all, but if we don't the text will be
|
|
||||||
* printed in a low resolution.
|
|
||||||
*/
|
|
||||||
class TextBufferDC : public wxMemoryDC {
|
|
||||||
public:
|
|
||||||
TextBufferDC(int width, int height, bool buffer_text);
|
|
||||||
|
|
||||||
virtual void DoDrawText(const String& str, int x, int y);
|
|
||||||
virtual void DoDrawRotatedText(const String& str, int x, int y, Radians angle);
|
|
||||||
|
|
||||||
/// Copy the contents of the DC to a target device, this DC becomes invalid
|
|
||||||
void drawToDevice(DC& dc, int x = 0, int y = 0);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// A call to DrawText
|
|
||||||
struct TextDraw : public IntrusivePtrBase<TextDraw> {
|
|
||||||
wxFont font;
|
|
||||||
Color color;
|
|
||||||
int x, y;
|
|
||||||
String text;
|
|
||||||
Radians angle;
|
|
||||||
double user_scale_x, user_scale_y;
|
|
||||||
|
|
||||||
TextDraw(wxFont font, Color color, double user_scale_x, double user_scale_y, int x, int y, String text, Radians angle = 0)
|
|
||||||
: font(font), color(color), x(x), y(y), text(text), angle(angle), user_scale_x(user_scale_x), user_scale_y(user_scale_y)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
typedef intrusive_ptr<TextDraw> TextDrawP;
|
|
||||||
private:
|
|
||||||
vector<TextDrawP> text;
|
|
||||||
Bitmap buffer;
|
|
||||||
bool buffer_text; ///< buffering text?
|
|
||||||
};
|
|
||||||
|
|
||||||
TextBufferDC::TextBufferDC(int width, int height, bool buffer_text)
|
|
||||||
: buffer(width, height, 32)
|
|
||||||
, buffer_text(buffer_text)
|
|
||||||
{
|
|
||||||
SelectObject(buffer);
|
|
||||||
// initialize to white
|
|
||||||
clearDC(*this,*wxWHITE_BRUSH);
|
|
||||||
}
|
|
||||||
void TextBufferDC::DoDrawText(const String& str, int x, int y) {
|
|
||||||
if (buffer_text) {
|
|
||||||
double usx,usy;
|
|
||||||
GetUserScale(&usx, &usy);
|
|
||||||
text.push_back( intrusive(new TextDraw(GetFont(), GetTextForeground(), usx, usy, x, y, str)) );
|
|
||||||
} else {
|
|
||||||
wxMemoryDC::DoDrawText(str,x,y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void TextBufferDC::DoDrawRotatedText(const String& str, int x, int y, Radians angle) {
|
|
||||||
if (buffer_text) {
|
|
||||||
double usx,usy;
|
|
||||||
GetUserScale(&usx, &usy);
|
|
||||||
text.push_back( intrusive(new TextDraw(GetFont(), GetTextForeground(), usx, usy, x, y, str, angle)) );
|
|
||||||
} else {
|
|
||||||
wxMemoryDC::DoDrawRotatedText(str,x,y,rad_to_deg(angle));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLARE_TYPEOF_COLLECTION(TextBufferDC::TextDrawP);
|
|
||||||
|
|
||||||
void TextBufferDC::drawToDevice(DC& dc, int x, int y) {
|
|
||||||
SelectObject(wxNullBitmap);
|
|
||||||
dc.DrawBitmap(buffer, x, y);
|
|
||||||
FOR_EACH(t, text) {
|
|
||||||
double usx,usy;
|
|
||||||
dc.GetUserScale(&usx, &usy);
|
|
||||||
dc.SetUserScale(usx * t->user_scale_x, usx * t->user_scale_y);
|
|
||||||
dc.SetFont (t->font);
|
|
||||||
dc.SetTextForeground(t->color);
|
|
||||||
if (!is_rad0(t->angle)) {
|
|
||||||
dc.DrawRotatedText(t->text, t->x + x, t->y + y, rad_to_deg(t->angle));
|
|
||||||
} else {
|
|
||||||
dc.DrawText(t->text, t->x + x, t->y + y);
|
|
||||||
}
|
|
||||||
dc.SetUserScale(usx, usy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Layout
|
// ----------------------------------------------------------------------------- : Layout
|
||||||
|
|
||||||
PageLayout::PageLayout()
|
PageLayout::PageLayout()
|
||||||
@@ -120,18 +26,27 @@ PageLayout::PageLayout()
|
|||||||
, rows(0), cols(0), card_landscape(false)
|
, rows(0), cols(0), card_landscape(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PageLayout::PageLayout(const StyleSheet& stylesheet, const RealSize& page_size)
|
void PageLayout::init(const StyleSheet& stylesheet, PageLayoutType type, const RealSize& page_size) {
|
||||||
: page_size(page_size)
|
this->page_size = page_size;
|
||||||
, margin_left(0), margin_right(0), margin_top(0), margin_bottom(0)
|
margin_left = margin_right = margin_top = margin_bottom = 0;
|
||||||
{
|
|
||||||
card_size.width = stylesheet.card_width * 25.4 / stylesheet.card_dpi;
|
card_size.width = stylesheet.card_width * 25.4 / stylesheet.card_dpi;
|
||||||
card_size.height = stylesheet.card_height * 25.4 / stylesheet.card_dpi;
|
card_size.height = stylesheet.card_height * 25.4 / stylesheet.card_dpi;
|
||||||
card_landscape = card_size.width > card_size.height;
|
card_landscape = card_size.width > card_size.height;
|
||||||
cols = int(floor(page_size.width / card_size.width));
|
cols = int(floor(page_size.width / card_size.width));
|
||||||
rows = int(floor(page_size.height / card_size.height));
|
rows = int(floor(page_size.height / card_size.height));
|
||||||
// distribute whitespace evenly
|
// spacing
|
||||||
margin_left = margin_right = card_spacing.width = (page_size.width - (cols * card_size.width )) / (cols + 1);
|
double hspace = (page_size.width - (cols * card_size.width ));
|
||||||
margin_top = margin_bottom = card_spacing.height = (page_size.height - (rows * card_size.height)) / (rows + 1);
|
double vspace = (page_size.height - (rows * card_size.height));
|
||||||
|
if (type == LAYOUT_NO_SPACE) {
|
||||||
|
// no space between cards
|
||||||
|
card_spacing.width = card_spacing.height = 0;
|
||||||
|
margin_left = margin_right = hspace / 2;
|
||||||
|
margin_top = vspace * 1./3; margin_bottom = vspace * 2./3; // most printers have more margin at the bottom
|
||||||
|
} else {
|
||||||
|
// distribute whitespace evenly
|
||||||
|
margin_left = margin_right = card_spacing.width = hspace / (cols + 1);
|
||||||
|
margin_top = margin_bottom = card_spacing.height = vspace / (rows + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Printout
|
// ----------------------------------------------------------------------------- : Printout
|
||||||
@@ -139,7 +54,7 @@ PageLayout::PageLayout(const StyleSheet& stylesheet, const RealSize& page_size)
|
|||||||
/// A printout object specifying how to print a specified set of cards
|
/// A printout object specifying how to print a specified set of cards
|
||||||
class CardsPrintout : public wxPrintout {
|
class CardsPrintout : public wxPrintout {
|
||||||
public:
|
public:
|
||||||
CardsPrintout(const SetP& set, const vector<CardP>& cards);
|
CardsPrintout(PrintJobP const& job);
|
||||||
/// Number of pages, and something else I don't understand...
|
/// Number of pages, and something else I don't understand...
|
||||||
virtual void GetPageInfo(int* pageMin, int* pageMax, int* pageFrom, int* pageTo);
|
virtual void GetPageInfo(int* pageMin, int* pageMax, int* pageFrom, int* pageTo);
|
||||||
/// Again, 'number of pages', strange wx interface
|
/// Again, 'number of pages', strange wx interface
|
||||||
@@ -150,24 +65,22 @@ class CardsPrintout : public wxPrintout {
|
|||||||
virtual bool OnPrintPage(int page);
|
virtual bool OnPrintPage(int page);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PageLayoutP layout;
|
PrintJobP job; ///< Cards to print
|
||||||
SetP set;
|
|
||||||
vector<CardP> cards; ///< Cards to print
|
|
||||||
DataViewer viewer;
|
DataViewer viewer;
|
||||||
double scale_x, scale_y; // priter pixel per mm
|
double scale_x, scale_y; // priter pixel per mm
|
||||||
|
|
||||||
inline int pageCount() {
|
int pageCount() {
|
||||||
return ((int)cards.size() + layout->cardsPerPage() - 1) / layout->cardsPerPage();
|
return job->num_pages();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a card, that is card_nr on this page, find the postion by asking the layout
|
/// Draw a card, that is card_nr on this page, find the postion by asking the layout
|
||||||
void drawCard(DC& dc, const CardP& card, int card_nr);
|
void drawCard(DC& dc, const CardP& card, int card_nr);
|
||||||
};
|
};
|
||||||
|
|
||||||
CardsPrintout::CardsPrintout(const SetP& set, const vector<CardP>& cards)
|
CardsPrintout::CardsPrintout(PrintJobP const& job)
|
||||||
: set(set), cards(cards)
|
: job(job)
|
||||||
{
|
{
|
||||||
viewer.setSet(set);
|
viewer.setSet(job->set);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardsPrintout::GetPageInfo(int* page_min, int* page_max, int* page_from, int* page_to) {
|
void CardsPrintout::GetPageInfo(int* page_min, int* page_max, int* page_from, int* page_to) {
|
||||||
@@ -180,10 +93,10 @@ bool CardsPrintout::HasPage(int page) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CardsPrintout::OnPreparePrinting() {
|
void CardsPrintout::OnPreparePrinting() {
|
||||||
int pw_mm, ph_mm;
|
if (job->layout.empty()) {
|
||||||
GetPageSizeMM(&pw_mm, &ph_mm);
|
int pw_mm, ph_mm;
|
||||||
if (!layout) {
|
GetPageSizeMM(&pw_mm, &ph_mm);
|
||||||
layout = intrusive(new PageLayout(*set->stylesheet, RealSize(pw_mm, ph_mm)));
|
job->layout.init(*job->set->stylesheet, job->layout_type, RealSize(pw_mm, ph_mm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,24 +111,24 @@ bool CardsPrintout::OnPrintPage(int page) {
|
|||||||
scale_x = (double)pw_px / pw_mm;
|
scale_x = (double)pw_px / pw_mm;
|
||||||
scale_y = (double)ph_px / ph_mm;
|
scale_y = (double)ph_px / ph_mm;
|
||||||
// print the cards that belong on this page
|
// print the cards that belong on this page
|
||||||
int start = (page - 1) * layout->cardsPerPage();
|
int start = (page - 1) * job->layout.cards_per_page();
|
||||||
int end = min((int)cards.size(), start + layout->cardsPerPage());
|
int end = min((int)job->cards.size(), start + job->layout.cards_per_page());
|
||||||
for (int i = start ; i < end ; ++i) {
|
for (int i = start ; i < end ; ++i) {
|
||||||
drawCard(dc, cards[i], i - start);
|
drawCard(dc, job->cards.at(i), i - start);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardsPrintout::drawCard(DC& dc, const CardP& card, int card_nr) {
|
void CardsPrintout::drawCard(DC& dc, const CardP& card, int card_nr) {
|
||||||
// determine position
|
// determine position
|
||||||
int col = card_nr % layout->cols;
|
int col = card_nr % job->layout.cols;
|
||||||
int row = card_nr / layout->cols;
|
int row = card_nr / job->layout.cols;
|
||||||
RealPoint pos( layout->margin_left + (layout->card_size.width + layout->card_spacing.width) * col
|
RealPoint pos( job->layout.margin_left + (job->layout.card_size.width + job->layout.card_spacing.width) * col
|
||||||
, layout->margin_top + (layout->card_size.height + layout->card_spacing.height) * row);
|
, job->layout.margin_top + (job->layout.card_size.height + job->layout.card_spacing.height) * row);
|
||||||
// determine rotation
|
// determine rotation
|
||||||
const StyleSheet& stylesheet = set->stylesheetFor(card);
|
const StyleSheet& stylesheet = job->set->stylesheetFor(card);
|
||||||
int rotation = 0;
|
int rotation = 0;
|
||||||
if ((stylesheet.card_width > stylesheet.card_height) != layout->card_landscape) {
|
if ((stylesheet.card_width > stylesheet.card_height) != job->layout.card_landscape) {
|
||||||
rotation = 90 - rotation;
|
rotation = 90 - rotation;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -223,8 +136,8 @@ void CardsPrintout::drawCard(DC& dc, const CardP& card, int card_nr) {
|
|||||||
RealSize card_size( stylesheet.card_width * 25.4 / stylesheet.card_dpi
|
RealSize card_size( stylesheet.card_width * 25.4 / stylesheet.card_dpi
|
||||||
, stylesheet.card_height * 25.4 / stylesheet.card_dpi);
|
, stylesheet.card_height * 25.4 / stylesheet.card_dpi);
|
||||||
if (rotation == 90) swap(card_size.width, card_size.height);
|
if (rotation == 90) swap(card_size.width, card_size.height);
|
||||||
// adjust card size, to center card in the available space (from layout->card_size)?
|
// adjust card size, to center card in the available space (from job->layout.card_size)?
|
||||||
// TODO
|
// TODO: deal with different sized cards in general
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// create buffers
|
// create buffers
|
||||||
@@ -232,7 +145,9 @@ void CardsPrintout::drawCard(DC& dc, const CardP& card, int card_nr) {
|
|||||||
if (rotation == 90) swap(w,h);
|
if (rotation == 90) swap(w,h);
|
||||||
// Draw using text buffer
|
// Draw using text buffer
|
||||||
double zoom = IsPreview() ? 1 : 4;
|
double zoom = IsPreview() ? 1 : 4;
|
||||||
TextBufferDC bufferDC(w*zoom,h*zoom,false);
|
wxBitmap buffer(w*zoom,h*zoom,32);
|
||||||
|
wxMemoryDC bufferDC(buffer);
|
||||||
|
clearDC(bufferDC,*wxWHITE_BRUSH);
|
||||||
RotatedDC rdc(bufferDC, rotation, stylesheet.getCardRect(), zoom, QUALITY_AA, ROTATION_ATTACH_TOP_LEFT);
|
RotatedDC rdc(bufferDC, rotation, stylesheet.getCardRect(), zoom, QUALITY_AA, ROTATION_ATTACH_TOP_LEFT);
|
||||||
// render card to dc
|
// render card to dc
|
||||||
viewer.setCard(card);
|
viewer.setCard(card);
|
||||||
@@ -241,49 +156,67 @@ void CardsPrintout::drawCard(DC& dc, const CardP& card, int card_nr) {
|
|||||||
double px_per_mm = zoom * stylesheet.card_dpi / 25.4;
|
double px_per_mm = zoom * stylesheet.card_dpi / 25.4;
|
||||||
dc.SetUserScale(scale_x / px_per_mm, scale_y / px_per_mm);
|
dc.SetUserScale(scale_x / px_per_mm, scale_y / px_per_mm);
|
||||||
dc.SetDeviceOrigin(int(scale_x * pos.x), int(scale_y * pos.y));
|
dc.SetDeviceOrigin(int(scale_x * pos.x), int(scale_y * pos.y));
|
||||||
bufferDC.drawToDevice(dc, 0, 0); // adjust for scaling
|
bufferDC.SelectObject(wxNullBitmap);
|
||||||
|
dc.DrawBitmap(buffer, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : PrintWindow
|
// ----------------------------------------------------------------------------- : PrintWindow
|
||||||
|
|
||||||
const vector<CardP>* cards_to_print(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices) {
|
PrintJobP make_print_job(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices) {
|
||||||
// Let the user choose cards
|
// Let the user choose cards
|
||||||
//CardSelectWindow wnd(parent, set, _LABEL_("select cards print"), _TITLE_("select cards"));
|
// controls
|
||||||
ExportWindowBase wnd(parent, _TITLE_("select cards"), set, choices);
|
ExportWindowBase wnd(parent, _TITLE_("select cards"), set, choices);
|
||||||
|
wxCheckBox* space = new wxCheckBox(&wnd, wxID_ANY, L"Put space between cards");
|
||||||
|
space->SetValue(settings.print_layout);
|
||||||
|
// layout
|
||||||
wxSizer* s = new wxBoxSizer(wxVERTICAL);
|
wxSizer* s = new wxBoxSizer(wxVERTICAL);
|
||||||
wxSizer* s2 = wnd.Create();
|
wxSizer* s2 = new wxBoxSizer(wxHORIZONTAL);
|
||||||
s->Add(s2, 1, wxEXPAND | wxALL, 8);
|
wxSizer* s3 = wnd.Create();
|
||||||
|
s2->Add(s3, 1, wxEXPAND | wxALL, 8);
|
||||||
|
wxSizer* s4 = new wxStaticBoxSizer(wxVERTICAL, &wnd, L"Settings");
|
||||||
|
s4->Add(space, 1, wxALL | wxALIGN_TOP, 8);
|
||||||
|
s2->Add(s4, 1, wxEXPAND | wxALL & ~wxLEFT, 8);
|
||||||
|
s->Add(s2, 1, wxEXPAND);
|
||||||
s->Add(wnd.CreateButtonSizer(wxOK | wxCANCEL) , 0, wxEXPAND | wxALL, 8);
|
s->Add(wnd.CreateButtonSizer(wxOK | wxCANCEL) , 0, wxEXPAND | wxALL, 8);
|
||||||
s->SetSizeHints(&wnd);
|
s->SetSizeHints(&wnd);
|
||||||
wnd.SetSizer(s);
|
wnd.SetSizer(s);
|
||||||
wnd.SetSize(300,-1);
|
wnd.SetMinSize(wxSize(300,-1));
|
||||||
// show window
|
// show window
|
||||||
if (wnd.ShowModal() != wxID_OK) {
|
if (wnd.ShowModal() != wxID_OK) {
|
||||||
return nullptr; // cancel
|
return PrintJobP(); // cancel
|
||||||
|
} else {
|
||||||
|
// make print job
|
||||||
|
PrintJobP job = intrusive(new PrintJob(set));
|
||||||
|
job->layout_type = settings.print_layout = space->GetValue() ? LAYOUT_EQUAL_SPACE : LAYOUT_NO_SPACE;
|
||||||
|
job->cards = wnd.getSelection();
|
||||||
|
return job;
|
||||||
}
|
}
|
||||||
return &wnd.getSelection();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_preview(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices) {
|
void print_preview(Window* parent, const PrintJobP& job) {
|
||||||
const vector<CardP>* cards = cards_to_print(parent, set, choices);
|
if (!job) return;
|
||||||
if (!cards) return;
|
|
||||||
// Show the print preview
|
// Show the print preview
|
||||||
wxPreviewFrame* frame = new wxPreviewFrame(
|
wxPreviewFrame* frame = new wxPreviewFrame(
|
||||||
new wxPrintPreview(
|
new wxPrintPreview(
|
||||||
new CardsPrintout(set, *cards),
|
new CardsPrintout(job),
|
||||||
new CardsPrintout(set, *cards)
|
new CardsPrintout(job)
|
||||||
), parent, _TITLE_("print preview"));
|
), parent, _TITLE_("print preview"));
|
||||||
frame->Initialize();
|
frame->Initialize();
|
||||||
frame->Maximize(true);
|
frame->Maximize(true);
|
||||||
frame->Show();
|
frame->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_set(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices) {
|
void print_set(Window* parent, const PrintJobP& job) {
|
||||||
const vector<CardP>* cards = cards_to_print(parent, set, choices);
|
if (!job) return;
|
||||||
if (!cards) return;
|
|
||||||
// Print the cards
|
// Print the cards
|
||||||
wxPrinter p;
|
wxPrinter p;
|
||||||
CardsPrintout pout(set, *cards);
|
CardsPrintout pout(job);
|
||||||
p.Print(parent, &pout, true);
|
p.Print(parent, &pout, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_preview(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices) {
|
||||||
|
print_preview(parent, make_print_job(parent, set, choices));
|
||||||
|
}
|
||||||
|
void print_set(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices) {
|
||||||
|
print_set(parent, make_print_job(parent, set, choices));
|
||||||
|
}
|
||||||
|
|||||||
+41
-16
@@ -12,27 +12,19 @@
|
|||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <util/reflect.hpp>
|
#include <util/reflect.hpp>
|
||||||
#include <util/real_point.hpp>
|
#include <util/real_point.hpp>
|
||||||
|
#include <data/settings.hpp>
|
||||||
#include <gui/card_select_window.hpp>
|
#include <gui/card_select_window.hpp>
|
||||||
|
|
||||||
DECLARE_POINTER_TYPE(Set);
|
DECLARE_POINTER_TYPE(Set);
|
||||||
|
DECLARE_POINTER_TYPE(PrintJob);
|
||||||
class StyleSheet;
|
class StyleSheet;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Printing
|
|
||||||
|
|
||||||
/// Show a print preview for the given set
|
|
||||||
void print_preview(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices);
|
|
||||||
|
|
||||||
/// Print the given set
|
|
||||||
void print_set(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Layout
|
// ----------------------------------------------------------------------------- : Layout
|
||||||
|
|
||||||
/// Layout of a page of cards
|
/// Layout of a page of cards
|
||||||
class PageLayout : public IntrusivePtrBase<PageLayout> {
|
class PageLayout {
|
||||||
public:
|
public:
|
||||||
PageLayout();
|
// layout
|
||||||
PageLayout(const StyleSheet& stylesheet, const RealSize& page_size);
|
|
||||||
|
|
||||||
RealSize page_size; ///< Size of a page (in millimetres)
|
RealSize page_size; ///< Size of a page (in millimetres)
|
||||||
RealSize card_size; ///< Size of a card (in millimetres)
|
RealSize card_size; ///< Size of a card (in millimetres)
|
||||||
RealSize card_spacing; ///< Spacing between cards (in millimetres)
|
RealSize card_spacing; ///< Spacing between cards (in millimetres)
|
||||||
@@ -40,12 +32,45 @@ class PageLayout : public IntrusivePtrBase<PageLayout> {
|
|||||||
int rows, cols; ///< Number of rows/columns of cards
|
int rows, cols; ///< Number of rows/columns of cards
|
||||||
bool card_landscape; ///< Are cards rotated to landscape orientation?
|
bool card_landscape; ///< Are cards rotated to landscape orientation?
|
||||||
|
|
||||||
/// The number of cards per page
|
PageLayout();
|
||||||
inline int cardsPerPage() const { return rows * cols; }
|
void init(const StyleSheet& stylesheet, PageLayoutType layout_type, const RealSize& page_size);
|
||||||
|
|
||||||
private:
|
/// Is this layout uninitialized?
|
||||||
DECLARE_REFLECTION();
|
inline bool empty() const { return cards_per_page() == 0; }
|
||||||
|
/// The number of cards per page
|
||||||
|
inline int cards_per_page() const { return rows * cols; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PrintJob : public IntrusivePtrBase<PrintJob> {
|
||||||
|
public:
|
||||||
|
PrintJob(SetP const& set) : set(set) {}
|
||||||
|
|
||||||
|
// set and cards to print
|
||||||
|
SetP set;
|
||||||
|
vector<CardP> cards;
|
||||||
|
|
||||||
|
// printing options
|
||||||
|
PageLayoutType layout_type;
|
||||||
|
PageLayout layout;
|
||||||
|
|
||||||
|
inline int num_pages() const {
|
||||||
|
int cards_per_page = max(1,layout.cards_per_page());
|
||||||
|
return (cards.size() + cards_per_page - 1) / cards_per_page;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Printing
|
||||||
|
|
||||||
|
/// Make a print job, by asking the user for options, and card selection
|
||||||
|
PrintJobP make_print_job(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices);
|
||||||
|
|
||||||
|
/// Show a print preview for the given set
|
||||||
|
void print_preview(Window* parent, const PrintJobP& job);
|
||||||
|
void print_preview(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices);
|
||||||
|
|
||||||
|
/// Print the given set
|
||||||
|
void print_set(Window* parent, const PrintJobP& job);
|
||||||
|
void print_set(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user