Class DeckPacker
- java.lang.Object
-
- ca.cgjennings.apps.arkham.project.DeckPacker
-
public class DeckPacker extends java.lang.Object
A deck packer lays out a deck of game components automatically. The layout algorithm is a modified bin-packing algorithm that balances producing a minimal page count against grouping the objects in the deck sensibly.- Since:
- 2.1
- Author:
- Chris Jennings
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected static class
DeckPacker.Card
This class represents one or more card faces in a form suitable for planning layouts.
-
Field Summary
Fields Modifier and Type Field Description protected boolean
layoutDebug
Subclasses may set this totrue
during testing.static int
QUALITY_FIT
The layout quality value that maximizes compactness.static int
QUALITY_SPEED
The layout quality value that maximizes layout speed.
-
Constructor Summary
Constructors Constructor Description DeckPacker()
Creates a new deck packer.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description boolean
add(java.io.File gcFile)
Adds one copy of a game component stored in a file to the resulting layout.boolean
add(java.io.File gcFile, int copies)
Reads a game component from a file and adds it to the resulting layout.protected void
addCard(DeckPacker.Card c)
Adds a card to the internal list of cards to include in the layout.protected void
addImpl(java.io.File f, GameComponent gc)
Called byadd(java.io.File)
to add a loaded game component to the layout.void
cancel()
Sets the cancellation flag.void
clear()
Removes all previously added games components.Deck
createLayout()
Create a deck layout using the current cards and layout options.void
createLayout(DeckEditor deckEditor)
Create a deck layout using the current cards and layout options.int
getLayoutQuality()
Returns the quality setting for the layout algorithm.PaperProperties
getPaper()
Returns the paper type used to create the layout.protected DeckPacker.Card[]
getSortedCards(java.util.Comparator<DeckPacker.Card> comp)
Returns an array of the cards that have been added for layout.boolean
isBleedMarginEnabled()
Returnstrue
if bleed margins should be added to faces.boolean
isCancelled()
Returnstrue
if the cancellation flag has been set.boolean
isGroupingEnabled()
Returnstrue
if front and back faces should be grouped together.boolean
isLayoutDoubleSided()
Returnstrue
if the layout will be designed for double-sided printing.protected void
layout(Deck deck)
Lays out a prepared deck and set of cards.protected void
place(Deck deck, int pageIndex, DeckPacker.Card c, double x, double y)
Places a card into a deck on a given page and position.protected void
prepareCard(DeckPacker.Card c)
This method prepares cards for layout once all of the layout requirements are known.void
setBleedMarginEnabled(boolean bleedMargin)
Sets whether bleed margins should be added to card faces.void
setGroupingEnabled(boolean groupCardPairs)
Sets whether front and back faces should be grouped together.void
setLayoutDoubleSided(boolean doubleSided)
Sets whether the layout will be designed for double-sided printing.void
setLayoutQuality(int quality)
Sets the layout algorithm quality setting.void
setPaper(PaperProperties paper)
Sets the paper format to use for laying out cards.
-
-
-
Field Detail
-
QUALITY_SPEED
public static final int QUALITY_SPEED
The layout quality value that maximizes layout speed.- See Also:
- Constant Field Values
-
QUALITY_FIT
public static final int QUALITY_FIT
The layout quality value that maximizes compactness.- See Also:
- Constant Field Values
-
layoutDebug
protected boolean layoutDebug
Subclasses may set this totrue
during testing. If the subclass usesplace(ca.cgjennings.apps.arkham.deck.Deck, int, ca.cgjennings.apps.arkham.project.DeckPacker.Card, double, double)
to add cards, then a sequence of images will be displayed showing how each card is placed.
-
-
Constructor Detail
-
DeckPacker
public DeckPacker()
Creates a new deck packer. The layout initially contains no game components and will target PA4-sized paper (assuming that paper size is installed in the application settings, which it is unless explicitly removed). PA4 layouts can be printed on both North American letter and ISO A4 paper.
-
-
Method Detail
-
add
public boolean add(java.io.File gcFile)
Adds one copy of a game component stored in a file to the resulting layout. This is a convenience foradd( gcFile, 1 )
.- Parameters:
gcFile
- the file containing the game component- Throws:
java.lang.NullPointerException
- if the game component file isnull
- See Also:
add(java.io.File, int)
-
add
public boolean add(java.io.File gcFile, int copies)
Reads a game component from a file and adds it to the resulting layout. Some kinds of components, such as other decks, cannot be added to a deck. Adding components of this type will have no effect on the resulting layout, and this method will returnfalse
to signal that the component was skipped. If an error occurs while loading the file, an error message will be displayed, the file will be skipped, and this method will returnfalse
.- Parameters:
gcFile
- the file containing the game componentcopies
- the number of copies of the game component to include- Returns:
true
if the file has been successfully added and the layout will change as a result- Throws:
java.lang.NullPointerException
- if the game component file isnull
java.lang.IllegalArgumentException
- if the number of copies is negative
-
addImpl
protected void addImpl(java.io.File f, GameComponent gc)
Called byadd(java.io.File)
to add a loaded game component to the layout. This method takes incoming game components and addsDeckPacker.Card
objects to the layout based on the game component's sheets.- Parameters:
f
- the file associated with the game componentgc
- the game component instance to add- See Also:
addCard(ca.cgjennings.apps.arkham.project.DeckPacker.Card)
-
clear
public void clear()
Removes all previously added games components.
-
addCard
protected final void addCard(DeckPacker.Card c)
Adds a card to the internal list of cards to include in the layout. Can be used by subclasses that overrideaddImpl(java.io.File, ca.cgjennings.apps.arkham.component.GameComponent)
to post theDeckPacker.Card
groupings that they create. Cards added with this method will later be returned fromgetSortedCards(java.util.Comparator)
.- Parameters:
c
- the card instance to be added
-
isLayoutDoubleSided
public boolean isLayoutDoubleSided()
Returnstrue
if the layout will be designed for double-sided printing.- Returns:
true
if double-sided layouts are enabled- See Also:
setLayoutDoubleSided(boolean)
-
setLayoutDoubleSided
public void setLayoutDoubleSided(boolean doubleSided)
Sets whether the layout will be designed for double-sided printing. Double-sided layouts place the front face of a component on an odd-numbered page, and the matching back face on the following page. The layout order of the following page is flipped horizontally so that they will line up correctly when printed.- Parameters:
doubleSided
- iftrue
, a double-sided layout is created
-
getLayoutQuality
public int getLayoutQuality()
Returns the quality setting for the layout algorithm.- Returns:
- the layout quality value
-
setLayoutQuality
public void setLayoutQuality(int quality)
Sets the layout algorithm quality setting. The quality setting is a value between 0 and 9 inclusive, where lower values favour speed over quality, and higher values favour quality over speed. Higher quality layouts try harder to pack components more neatly and/or into a smaller number of pages.- Parameters:
quality
- the quality setting, fromQUALITY_SPEED
toQUALITY_FIT
-
getPaper
public PaperProperties getPaper()
Returns the paper type used to create the layout.- Returns:
- the paper type that determines the size of pages and margin in the layout
-
setPaper
public void setPaper(PaperProperties paper)
Sets the paper format to use for laying out cards. The paper's size and margin determine the area available to lay out components on each page.- Parameters:
paper
- the paper type that determines the size of pages and margin in the layout- Throws:
java.lang.NullPointerException
- if the paper isnull
-
createLayout
public Deck createLayout()
Create a deck layout using the current cards and layout options. This method creates and returns a new deck.- Returns:
- a new deck object containing the laid out cards
-
createLayout
public void createLayout(DeckEditor deckEditor)
Create a deck layout using the current cards and layout options. This method uses the deck of the supplied editor. The deck is expected to be new and empty.- Parameters:
deckEditor
- the deck that will contain the laid out cards
-
layout
protected void layout(Deck deck)
Lays out a prepared deck and set of cards. Subclasses may override this to use a different bin packing algorithm. The passed-in deck is the destination for the layout, and cannot benull
. The paper size for the layout can be obtained by callingdeck.getPaperProperties()
.- Parameters:
deck
- the deck that should contain the details of the layout- Throws:
java.util.concurrent.CancellationException
- if the cancellation flag was set while computing the card layout
-
place
protected void place(Deck deck, int pageIndex, DeckPacker.Card c, double x, double y)
Places a card into a deck on a given page and position.- Parameters:
deck
- the deck to place the component inpageIndex
- the index of the page within the deck; if the page does not exist it is createdc
- the card to addx
- the x-coordinate to place the card aty
- the y-coordinate to place the card at
-
prepareCard
protected void prepareCard(DeckPacker.Card c)
This method prepares cards for layout once all of the layout requirements are known. The base class fills in the width, height, and area for a card; if not making a double-sided deck, then the two faces of a double-sided card are treated as a single unit and the sizes are set appropriately.- Parameters:
c
- the card to prepare
-
getSortedCards
protected DeckPacker.Card[] getSortedCards(java.util.Comparator<DeckPacker.Card> comp)
Returns an array of the cards that have been added for layout. If the comparatorcomp
is non-null
then it will be used to determine the sort order. Otherwise, a default sort order is used based onCard
'sComparable
implementation. The default order is suited to the base implementation's bin packing algorithm. Subclasses may substitute a different comparison function suited for other algorithms.
-
isGroupingEnabled
public boolean isGroupingEnabled()
Returnstrue
if front and back faces should be grouped together. This has no effect if double-sided layout is enabled.- Returns:
true
if grouping is enabled
-
setGroupingEnabled
public void setGroupingEnabled(boolean groupCardPairs)
Sets whether front and back faces should be grouped together. This has no effect if double-sided layout is enabled.- Parameters:
groupCardPairs
- iftrue
, front and back faces placed side-by-side will be placed into a group
-
isBleedMarginEnabled
public boolean isBleedMarginEnabled()
Returnstrue
if bleed margins should be added to faces.- Returns:
true
if bleed margins are enabled
-
setBleedMarginEnabled
public void setBleedMarginEnabled(boolean bleedMargin)
Sets whether bleed margins should be added to card faces.- Parameters:
bleedMargin
-
-
cancel
public final void cancel()
Sets the cancellation flag. If a deck is being laid out, this will cause the layout algorithm to throw an exception. It can be called in response to user requests to cancel the layout operation.
-
isCancelled
public final boolean isCancelled()
Returnstrue
if the cancellation flag has been set.- Returns:
true
if the layout operation has been cancelled- See Also:
cancel()
-
-