![]()
This tutorial introduces printing with the "printer" program. The program consists of a window where the user can draw lines and a print button. When the user pushed the print button, the lines shown in the window are printed. This program is made up of five files - the source and header for the object that contains the window, the source and header for the printing widget and the source that contains the function main.
PrintWidget source file:
/******************************************************************************
PrintWidget.cc
BASE CLASS = JXWindowDirector
Written by Glenn Bach - 1997.
******************************************************************************/
#include "PrintWidget.h"
#include <JXApplication.h>
#include <JXWidget.h>
#include <JXWindowPainter.h>
#include <JXDragPainter.h>
#include <JXColormap.h>
#include <jXGlobals.h>
#include <JPrinter.h>
#include <jAssert.h>
/******************************************************************************
Constructor
******************************************************************************/
PrintWidget::PrintWidget
(
JXScrollbarSet* scrollbarSet,
JXContainer*
enclosure,
const HSizingOption hSizing,
const VSizingOption vSizing,
const JCoordinate x,
const JCoordinate y,
const JCoordinate w,
const JCoordinate h
)
:
JXScrollableWidget(scrollbarSet, enclosure,
hSizing, vSizing, x, y, w, h)
{
// This changes our Bounds,
independent of what part of us
// is visible (our Frame).
SetBounds(500, 400);
// This array keeps track
of the points that define the beginning and
// ending of each line
the is draw in the window.
// See JCollection.h, JOrderedSet.h, and JArray.h for functionality
itsPoints = new JArray<JPoint>();
assert( itsPoints != NULL );
}
/******************************************************************************
Destructor
******************************************************************************/
PrintWidget::~PrintWidget()
{
// Unlike widgets, which
are automatically deleted by the framework,
// we must delete this
JArray since it is a private instance variable.
delete itsPoints;
}
/*****************************************************************************
Print
******************************************************************************/
void
PrintWidget::Print
(
JPrinter& p
)
{
// Calculate the height
needed for the header
const JCoordinate headerHeight = p.JPainter::GetLineHeight();
// Start the print document
p.OpenDocument();
// This will return false
if the print job was cancelled
if (p.NewPage())
{
// draw the header
JRect pageRect = p.GetPageRect();
p.String(pageRect.left,
pageRect.top, "Printing Test",
pageRect.width(), JPainter::kHAlignCenter);
p.LockHeader(headerHeight);
// draw the page
// Printing and drawing to the screen use the same code
DrawStuff(p);
// Finish the print job
p.CloseDocument();
}
}
/******************************************************************************
Draw (virtual protected)
This gets called by the
event loop every time the Widget needs to
be redrawn.
******************************************************************************/
void
PrintWidget::Draw
(
JXWindowPainter& p,
const JRect& rect
)
{
// This needs to be out
of the main drawing routing, because
// we don't want this
to print
p.String(10, 10, "Type 'c' to clear, 'q' to
quit.", 200,
JPainter::kHAlignLeft, p.GetLineHeight());
// Call the generic drawing
routing (same for printing)
DrawStuff(p);
}
/******************************************************************************
DrawStuff (private)
******************************************************************************/
void
PrintWidget::DrawStuff
(
JPainter& p
)
{
// Set pen color
p.SetPenColor((GetColormap())->GetBlackColor());
// Find out how many points
there are
// There are count/2 lines
JSize count = itsPoints->GetElementCount();
// Loop through the points
by twos
for (JSize i = 1; i <= count; i += 2)
{
// Draw the line
p.Line(itsPoints->GetElement(i),
itsPoints->GetElement(i+1));
}
}
/******************************************************************************
HandleMouseDown (virtual protected)
This gets called by the event loop every time a mouse button is pressed.
pt is where the mouse was clicked, in Bounds coordinates.
button is the index of the mouse button being pressed.
clickCount is the number
of times that this button has been pressed
in rapid succession.
buttonStates tells the
state of all the mouse buttons.
Refer to JXButtonStates.h
for more information.
modifiers contains information
about modifier keys like Shift and
Control. Refer to
JXKeyModifiers.h for more information.
******************************************************************************/
void
PrintWidget::HandleMouseDown
(
const JPoint&
pt,
const JXMouseButton
button,
const JSize
clickCount,
const JXButtonStates&
buttonStates,
const JXKeyModifiers&
modifiers
)
{
// Check to see if the
left button was pressed
if (button == kJXLeftButton)
{
// Create the drag painter to draw the rubber-band like lines
JPainter* p = CreateDragInsidePainter();
// Start the first line
p->Line(pt, pt);
}
// Initialize the current
points
itsStartPt = itsPrevPt = pt;
}
/******************************************************************************
HandleMouseDrag (virtual protected)
This gets called as often
as possible by the event loop as long as
a mouse button is pressed.
pt is where the mouse is, in Bounds coordinates.
buttonStates tells the
state of all the mouse buttons.
Refer to JXButtonStates.h
for more information.
modifiers contains information
about modifier keys like Shift and
Control. Refer to
JXKeyModifiers.h for more information.
******************************************************************************/
void
PrintWidget::HandleMouseDrag
(
const JPoint&
pt,
const JXButtonStates&
buttonStates,
const JXKeyModifiers&
modifiers
)
{
// Check to see if the
window was scrolled
const JBoolean scrolled = ScrollForDrag(pt);
// Get the drag painter
that we created in mouse down
JPainter* p = GetDragPainter();
// Make sure that the left
button is pressed,
// that we have moved,
// and that a drag painter
exists
if (buttonStates.left() && pt != itsPrevPt
&& p != NULL) // p is NULL for multiple click
{
// Draw line depending on whether or not we scrolled
if (!scrolled)
{
p->Line(itsStartPt, itsPrevPt);
}
p->Line(itsStartPt,
pt);
}
// Remember the current
point
itsPrevPt = pt;
}
/******************************************************************************
HandleMouseUp (virtual protected)
This gets called by the event loop every time a mouse button is released.
pt is where the mouse was released, in Bounds coordinates.
button is the index of the mouse button being pressed.
buttonStates tells the
state of all the mouse buttons.
Refer to JXButtonStates.h
for more information.
modifiers contains information
about modifier keys like Shift and
Control. Refer to
JXKeyModifiers.h for more information.
******************************************************************************/
void
PrintWidget::HandleMouseUp
(
const JPoint&
pt,
const JXMouseButton
button,
const JXButtonStates&
buttonStates,
const JXKeyModifiers&
modifiers
)
{
// Get the drag painter
that we created in mouse down
JPainter* p = GetDragPainter();
// Make sure that the left
button is pressed,
// and that a drag painter
exists
if (button == kJXLeftButton && p !=
NULL) // p is NULL for multiple click
{
// Erase the last line that was drawn
p->Line(itsStartPt,
itsPrevPt);
// Delete the drag painter
DeleteDragPainter();
// Add this set of points to our JArray
itsPoints->AppendElement(itsStartPt);
itsPoints->AppendElement(itsPrevPt);
// Tell the widget to redraw itself
Refresh();
}
}
/******************************************************************************
HandleKeyPress (virtual)
This gets called by the event loop every time a key is pressed.
If the key that was pressed
had an ASCII equivalent, then 'key'
contains the ASCII value.
Otherwise, 'key' contains the X KeySym
value, as defined in X11/keysym.h.
modifiers contains information
about modifier keys like Shift and
Control. Refer to
JXKeyModifiers.h for more information.
******************************************************************************/
void
PrintWidget::HandleKeyPress
(
const int key,
const JXKeyModifiers& modifiers
)
{
// Check if the 'c' key
was pressed
// If so, we want to clear
the window
if (key == 'c')
{
// remove all of the points from the JArray
itsPoints->RemoveAll();
// Redraw
Refresh();
}
// Check if the 'q' key
was pressed
else if (key == 'q')
{
// Quit the application if 'q' was pressed
(JXGetApplication())->Quit();
}
// If anything else was
pressed, pass it up the inheritance tree
else
{
JXScrollableWidget::HandleKeyPress(key,modifiers);
}
}
PrintWidget header file:
/******************************************************************************
PrintWidget.h
Interface for the PrintWidget class
Written by Glenn Bach - 1997.
******************************************************************************/
#ifndef _H_PrintWidget
#define _H_PrintWidget
#include <JXScrollableWidget.h>
#include <JArray.h>
class JPrinter;
class JPainter;
class PrintWidget : public JXScrollableWidget
{
public:
PrintWidget(JXScrollbarSet* scrollbarSet, JXContainer*
enclosure,
const HSizingOption hSizing, const VSizingOption vSizing,
const JCoordinate x, const JCoordinate y,
const JCoordinate w, const JCoordinate h);
virtual ~PrintWidget();
void Print(JPrinter& p);
virtual void HandleKeyPress(const
int key,
const JXKeyModifiers& modifiers);
protected:
virtual void Draw(JXWindowPainter&
p, const JRect& rect);
virtual void HandleMouseDown(const
JPoint& pt, const JXMouseButton button,
const JSize clickCount,
const JXButtonStates& buttonStates,
const JXKeyModifiers& modifiers);
virtual void HandleMouseDrag(const
JPoint& pt, const JXButtonStates& buttonStates,
const JXKeyModifiers& modifiers);
virtual void HandleMouseUp(const
JPoint& pt, const JXMouseButton button,
const JXButtonStates& buttonStates,
const JXKeyModifiers& modifiers);
private:
// used during drag
JPoint itsStartPt;
JPoint itsPrevPt;
JArray<JPoint>* itsPoints;
private:
void DrawStuff(JPainter& p);
// not allowed
PrintWidget(const PrintWidget& source);
const PrintWidget& operator=(const PrintWidget&
source);
};
#endif
PrintWidgetDir source file:
/******************************************************************************
PrintWidgetDir.cc
BASE CLASS = JXWindowDirector
Written by Glenn Bach - 1997.
******************************************************************************/
#include "PrintWidgetDir.h"
#include "PrintWidget.h"
#include <JXWindow.h>
#include <JXScrollbarSet.h>
#include <JXPSPrinter.h>
#include <JXTextButton.h>
#include <JXDialogDirector.h>
#include <jAssert.h>
/******************************************************************************
Constructor
******************************************************************************/
PrintWidgetDir::PrintWidgetDir
(
JXDirector* supervisor
)
:
JXWindowDirector(supervisor)
{
BuildWindow();
// Create the printer object
itsPrinter = new JXPSPrinter(GetDisplay(), (GetWindow())->GetColormap());
assert( itsPrinter != NULL );
// Initialize the print
setup dialog box - its created as needed
itsPrintSetupDialog = NULL;
}
/******************************************************************************
Destructor
******************************************************************************/
PrintWidgetDir::~PrintWidgetDir()
{
// We need to delete this,
the window will delete everything else
delete itsPrinter;
}
/******************************************************************************
Receive (virtual protected)
******************************************************************************/
void
PrintWidgetDir::Receive
(
JBroadcaster* sender,
const Message& message
)
{
// Check if the print
button was pressed
if (sender == itsPrintButton && message.Is(JXButton::kPushed))
{
// Start the printing process by opening the dialog
itsPrintSetupDialog
= itsPrinter->BeginUserPrintSetup(this);
// We need to know when the dialog has closed
ListenTo(itsPrintSetupDialog);
}
// This is the dialog's
closing message
else if (sender == itsPrintSetupDialog &&
message.Is(JXDialogDirector::kDeactivated))
{
// See if the user cancelled the print job
if (itsPrinter->EndUserPrintSetup(message))
{
// If the user didn't cancel, print
itsWidget->Print(*itsPrinter);
}
// The dialog will be deleted automatically
itsPrintSetupDialog
= NULL;
}
else
{
// Pass the message up the inheritance tree
JXWindowDirector::Receive(sender,
message);
}
}
/******************************************************************************
BuildWindow
This is a convenient and organized way of putting all of the initial
elements into a
window. This will keep the constructor less cluttered.
******************************************************************************/
void
PrintWidgetDir::BuildWindow()
{
// Create the window
JXWindow* window = new JXWindow(this, 300,200,
"Printing Test Program");
assert( window != NULL );
// Give the window to the
director
SetWindow(window);
// Set the window sizing
window->SetMinSize(300,200);
window->SetMaxSize(800,600);
// Create the print button
itsPrintButton =
new JXTextButton("Print",
window,
JXWidget::kHElastic, JXWidget::kVElastic,
0, 0, 300, 20);
// We need to hear when
the button has been pressed
ListenTo(itsPrintButton);
// Create the scrollbar
set
JXScrollbarSet* scrollbarSet =
new JXScrollbarSet(window,
JXWidget::kHElastic, JXWidget::kVElastic, 0,20, 300,180);
assert( scrollbarSet != NULL );
// Create the custom widget
with the scrollbarset as its enclosure
PrintWidget* widget =
new PrintWidget(scrollbarSet,
scrollbarSet->GetScrollEnclosure(),
JXWidget::kHElastic, JXWidget::kVElastic,
0, 0, 10, 10);
assert( widget != NULL );
// Fit the widget within
the scrollbarset enclosure
widget->FitToEnclosure(kTrue, kTrue);
itsWidget = widget;
}
PrintWidgetDir header file:
/******************************************************************************
PrintWidgetDir.h
Interface for the PrintWidgetDir class
Written by Glenn Bach - 1997.
******************************************************************************/
#ifndef _H_PrintWidgetDir
#define _H_PrintWidgetDir
#include <JXWindowDirector.h>
class JXPSPrinter;
class PrintWidget;
class JXTextButton;
class JXDialogDirector;
class PrintWidgetDir : public JXWindowDirector
{
public:
PrintWidgetDir(JXDirector* supervisor);
virtual ~PrintWidgetDir();
protected:
virtual void Receive(JBroadcaster* sender, const Message& message);
private:
JXPSPrinter*
itsPrinter;
JXDialogDirector* itsPrintSetupDialog;
PrintWidget*
itsWidget;
JXTextButton*
itsPrintButton;
private:
void BuildWindow();
// not allowed
PrintWidgetDir(const PrintWidgetDir& source);
const PrintWidgetDir& operator=(const PrintWidgetDir&
source);
};
#endif
******************************************************************************/
#include "PrintWidgetDir.h"
#include <JXApplication.h>
#include <jAssert.h>
/******************************************************************************
main
******************************************************************************/
int
main
(
int argc,
char* argv[]
)
{
// Create the application
JXApplication* app = new JXApplication(&argc,
argv);
assert( app != NULL );
// Create the window director
PrintWidgetDir* mainDir = new PrintWidgetDir(app);
assert( mainDir != NULL );
// Activate the window
director
mainDir->Activate();
// Start the event loop
app->Run();
return 0;
}