OpDragBox Class Reference

This is a base class for operations that use a drag box to select an area within a view, such as the selector and the zoom tools. This class looks after the chore of correctly drawing and updating the xored drag box. More...

#include <opdragbx.h>

Inheritance diagram for OpDragBox:

Operation MessageHandler ListItem CCObject SimpleCCObject OpCentredDragBox OpZoom OpZoomIn OpZoomOut OpZoomTo100 OpZoomTo200 OpZoomTo300 OpZoomTo400 List of all members.

Public Member Functions

BOOL DoDrag (DragType dt, Spread *pStartSpread, const DocCoord &dcStartPos, ClickModifiers cmods)

Static Public Member Functions

static BOOL Init ()
 Initialises the OpDragBox base-class drag operation. Loads preferences.

Protected Member Functions

 OpDragBox ()
 Default constructor. Only accessible to derived classes.
virtual BOOL OnDragStarted (Spread *pStartSpread, const DocCoord &dcStartPos, ClickModifiers cmods)
virtual BOOL OnPointerMoved (Spread *pBoxSpread, const DocRect &drDragBox, ClickModifiers cmods)
virtual BOOL OnPointerIdle (Spread *pBoxSpread, const DocRect &drDragBox, ClickModifiers cmods)
virtual BOOL OnDragEnded (Spread *pBoxSpread, const DocRect &drDragBox, ClickModifiers cmods, BOOL fDragOK)
virtual DocRect CalcDragBox (const DocCoord &dcStartPos, const DocCoord &dcMousePos) const
virtual StockColour GetBoxColour () const
 Allows customisation of the colour of the drag box.
BOOL GetDragStartPos (Spread **ppStartSpread, DocCoord *pdcStartPos) const
 Gets the the start position of the drag operation, if one has been started. Note that either of the output paramters may be NULL, which means that the caller doesn't require that particular output.

Static Protected Member Functions

static MILLIPOINT Min (MILLIPOINT a, MILLIPOINT b)
 Helper function to return the smallest of two ordinates.
static MILLIPOINT Max (MILLIPOINT a, MILLIPOINT b)
 Helper function to return the largest of two ordinates.

Private Member Functions

void DragPointerMove (DocCoord dcMousePos, ClickModifiers cmods, Spread *pSpread, BOOL bSolidDrag)
 This is called every time the mouse moves, during a drag. It updates the xored drag box and calls the OnPointerMoved function so a derived class can do something useful.
void DragPointerIdle (DocCoord dcMousePos, ClickModifiers cmods, Spread *pSpread, BOOL bSolidDrag)
 This is called every time the mouse hasn't moved for a while during a drag. It calls the OnPointerIdle function so a derived class can do something useful with this time, such as hit-testing etc.
void DragFinished (DocCoord dcMousePos, ClickModifiers cmods, Spread *pSpread, BOOL fOK, BOOL bSolidDrag)
 Pure virtual function which tells the operation that a drag has finished. Once the operation knows the drag has finished it should call EndDrag() to terminate the drag.
void RenderDragBlobs (DocRect drClipRect, Spread *pRenderSpread, BOOL bSolidDrag)
 Xors a rectangle onto the screen to mark out the size of the current drag box.
void UpdateSolidDragBox (const DocRect &drNewDragBox)
 Calculates which rectangles to xor to change the last drawn solid drag box into the new solid drag box.
void UpdateUnfilledDragBox (const DocRect &drNewDragBox)
 Calculates which rectangles to xor to change the last drawn solid drag box into the new solid drag box.
void DrawXorRect (const DocRect &drClip, Spread *pspdXor, const DocRect &drXor) const
 CC_DECLARE_DYNCREATE (OpDragBox)

Private Attributes

Spreadm_pStartSpread
DocCoord m_dcStartPos
DocRect m_drLastDragBox

Static Private Attributes

static BOOL m_fDoSolidDragBoxes = FALSE
 Determines how the drag operation base-class draws a drag box. If FALSE then the "tranditional" unfilled xor rectangle with a certain line colour is drawn. If FALSE a filled ("solid") xor rectangle of a certain line and fill colour will be drawn. The default is FALSE.

Detailed Description

This is a base class for operations that use a drag box to select an area within a view, such as the selector and the zoom tools. This class looks after the chore of correctly drawing and updating the xored drag box.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/4/95
To use this class derive a new operation from it and override the OnDragEnded function to do something useful with the drag box it is passed. You can optionally also override the OnDragStarted, OnPointerMoved, or OnPointerIdle functions, eg. to set status text or perform intermediate calculations, and the SetBoxColours and CalcDragRect functions to customise the "look and feel" of the drag box.

To run a drag, create an instance of your derived class and call its DoDrag() function, passing the mouse position etc that should be available in a tool.

See also:
class OpCentredDragBox

Definition at line 143 of file opdragbx.h.


Constructor & Destructor Documentation

OpDragBox::OpDragBox  )  [protected]
 

Default constructor. Only accessible to derived classes.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/93
See also:
class OpCentredDragBox

Definition at line 167 of file opdragbx.cpp.

00168   : m_pStartSpread(NULL)            // no drag has been started yet
00169 {
00170     // Empty.
00171 }


Member Function Documentation

DocRect OpDragBox::CalcDragBox const DocCoord dcStartPos,
const DocCoord dcMousePos
const [protected, virtual]
 

Reimplemented in OpCentredDragBox, and OpZoom.

Definition at line 562 of file opdragbx.cpp.

00563 {
00564     return DocRect(Min(dcStartPos.x, dcMousePos.x),
00565                    Min(dcStartPos.y, dcMousePos.y),
00566                    Max(dcStartPos.x, dcMousePos.x),
00567                    Max(dcStartPos.y, dcMousePos.y));
00568 }

OpDragBox::CC_DECLARE_DYNCREATE OpDragBox   )  [private]
 

BOOL OpDragBox::DoDrag DragType  dt,
Spread pStartSpread,
const DocCoord dcStartPos,
ClickModifiers  cmods
 

Definition at line 191 of file opdragbx.cpp.

00193 {
00194     // We use a null spread to indicate that a drag hasn't started yet, so check for this
00195     // when we reckon we should have a valid spread.
00196     ERROR3IF(pStartSpread == NULL, "Null StartSpread* passed to OpDragBox::DoDrag");
00197     
00198     // Initialise the drag box record to an empty rectangle.
00199     m_drLastDragBox.lo = m_drLastDragBox.hi = dcStartPos;
00200 
00201     // Try to start the drag.  Note that we don't touch m_pStartSpread if start drag fails,
00202     // so GetDragStartPos will correctly return "no drag started" if the StartDrag call
00203     // below fails.
00204     return StartDrag(dt) && OnDragStarted(m_pStartSpread = pStartSpread,
00205                                           m_dcStartPos = dcStartPos,
00206                                           cmods);
00207 }

void OpDragBox::DragFinished DocCoord  dcMousePos,
ClickModifiers  cmods,
Spread pSpread,
BOOL  fOK,
BOOL  bSolidDrag
[private, virtual]
 

Pure virtual function which tells the operation that a drag has finished. Once the operation knows the drag has finished it should call EndDrag() to terminate the drag.

virtual void Operation::DragFinished( DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL Success, BOOL bSolidDrag)

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/7/93
Parameters:
PointerPos,: Position of the mouse pointer [INPUTS] ClickMods: Click modifiers Success: Indicates if the drag was terminated by the user pressing escape (FALSE) or by the user releasing the mouse buttons (TRUE).
- [OUTPUTS]
Returns:
-

Errors: -

See also:
ClickModifiers

Reimplemented from Operation.

Definition at line 458 of file opdragbx.cpp.

00460 {
00461     // Remove the last drag box.
00462     RenderDragBlobs(m_drLastDragBox, m_pStartSpread, bSolidDrag);
00463 
00464     // It's possible that the mouse is in a different position to where it was on the last
00465     // call to DragPointerMove, so recalculate the drag box (but don't draw it, of course).
00466     // Here, check for a change in the spread containing the mouse.
00467     if (pSpread != m_pStartSpread && pSpread != NULL)
00468     {
00469         dcMousePos = MakeRelativeToSpread(m_pStartSpread, pSpread, dcMousePos);
00470     }
00471 
00472     // Recalculate the drag box.
00473     m_drLastDragBox = CalcDragBox(m_dcStartPos, dcMousePos);
00474 
00475     // Call the derived class handler, passing the drag box and the success code.
00476     if (!OnDragEnded(m_pStartSpread, m_drLastDragBox, cmods, EndDrag() && fOK))
00477     {
00478         FailAndExecute();
00479     }
00480 
00481     // Finally, end the operation.
00482     End();
00483 }

void OpDragBox::DragPointerIdle DocCoord  dcMousePos,
ClickModifiers  cmods,
Spread pSpread,
BOOL  bSolidDrag
[private, virtual]
 

This is called every time the mouse hasn't moved for a while during a drag. It calls the OnPointerIdle function so a derived class can do something useful with this time, such as hit-testing etc.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/7/93
Parameters:
dcMousePos the current position of the mouse [INPUTS] cmods the state of the mouse modifiers pSpread the spread containing the mouse
See also:
OpDragBox::OnPointerIdle

Reimplemented from Operation.

Definition at line 419 of file opdragbx.cpp.

00420 {
00421     // If the mouse has moved to another spread than translate its position into the
00422     // new spread's coordinate system.
00423     if (pSpread != m_pStartSpread && pSpread != NULL)
00424     {
00425         dcMousePos = MakeRelativeToSpread(m_pStartSpread, pSpread, dcMousePos);
00426     }
00427 
00428     // Calculate the new drag rectangle.  Note that as the mouse is supposed to be
00429     // stationary we do NOT redraw the drag box or update our records of it.
00430     DocRect drNewDragBox = CalcDragBox(m_dcStartPos, dcMousePos);
00431     
00432     // Call the derived class, optionally cancelling the drag.
00433     if (!OnPointerIdle(m_pStartSpread, drNewDragBox, cmods))
00434     {
00435         // Cancel the drag and operation.
00436         EndDrag();
00437         End();
00438     }
00439 }

void OpDragBox::DragPointerMove DocCoord  dcMousePos,
ClickModifiers  cmods,
Spread pSpread,
BOOL  bSolidDrag
[private, virtual]
 

This is called every time the mouse moves, during a drag. It updates the xored drag box and calls the OnPointerMoved function so a derived class can do something useful.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/7/93
Parameters:
dcMousePos the current position of the mouse [INPUTS] cmods the state of the mouse modifiers pSpread the spread containing the mouse
See also:
OpDragBox::OnPointerMoved; OpDragBox::UpdateSolidDragBox; OpDragBox::UpdateUnfilledDragBox

Reimplemented from Operation.

Definition at line 283 of file opdragbx.cpp.

00284 {
00285     // If the mouse has moved to another spread than translate its position into the
00286     // new spread's coordinate system.
00287     if (pSpread != m_pStartSpread && pSpread != NULL)
00288     {
00289         dcMousePos = MakeRelativeToSpread(m_pStartSpread, pSpread, dcMousePos);
00290     }
00291 
00292     // Calculate the new drag rectangle.
00293     DocRect drNewDragBox = CalcDragBox(m_dcStartPos, dcMousePos);
00294     ERROR3IF(!drNewDragBox.IsValid(), "Invalid drag box in OpDragBox::DragPointerMove");
00295 
00296     // Call the appropriate update function, according to whether we are drawing solid
00297     // drag boxes or unfilled drag boxes.
00298     if (m_fDoSolidDragBoxes)
00299     {
00300         UpdateSolidDragBox(drNewDragBox);
00301     }
00302     else
00303     {
00304         UpdateUnfilledDragBox(drNewDragBox);
00305     }
00306     
00307     // Update our record of the last drag box and call the derived class.
00308     if (!OnPointerMoved(m_pStartSpread, m_drLastDragBox = drNewDragBox, cmods))
00309     {
00310         // Cancel the drag and operation.
00311         EndDrag();
00312         End();
00313     }
00314 }

void OpDragBox::DrawXorRect const DocRect drClip,
Spread pspdXor,
const DocRect drXor
const [private]
 

Definition at line 519 of file opdragbx.cpp.

00520 {
00521     // Check if we have nothing to do.
00522     if (drXor.IsEmpty()) return;
00523 
00524     // Ask the derived class what colour its drag box is.  If we are doing solid drags we
00525     // want to use the same colour to fill the box as well, otherwise we fill with no colour.
00526     StockColour scLineColour = GetBoxColour();
00527     StockColour scFillColour = (m_fDoSolidDragBoxes) ? scLineColour : COLOUR_NONE;
00528     
00529     // Xor the rect on all supplied render-regions.
00530     RenderRegion* pRegion = DocView::RenderOnTop(&((DocRect&) drClip), pspdXor, ClippedEOR);
00531     while (pRegion != NULL)
00532     {
00533         // Set the line and fill colours.
00534         pRegion->SetLineColour(scLineColour);
00535         pRegion->SetFillColour(scFillColour);
00536 
00537         // Draw the xored drag box and go on to the next render-region.
00538         pRegion->DrawDragRect(&((DocRect&) drXor));
00539         pRegion = DocView::GetNextOnTop(&((DocRect&) drClip));
00540     }
00541 }

StockColour OpDragBox::GetBoxColour  )  const [protected, virtual]
 

Allows customisation of the colour of the drag box.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/4/95
Returns:
The stock colour of the drag box's line. By default this is COLOUR_XORSELECT.
See also:
OpDragBox::DrawXorRect

Definition at line 583 of file opdragbx.cpp.

00584 {
00585     return COLOUR_XORSELECT;
00586 }

BOOL OpDragBox::GetDragStartPos Spread **  ppStartSpread,
DocCoord pdcStartPos
const [protected]
 

Gets the the start position of the drag operation, if one has been started. Note that either of the output paramters may be NULL, which means that the caller doesn't require that particular output.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/4/95
Parameters:
ppStartSpread where to store the spread that the drag started on [OUTPUTS] pdcStartPos where to store the position that the drag started
Returns:
TRUE if a drag has been started, FALSE if one hasn't been started yet

Definition at line 224 of file opdragbx.cpp.

00225 {
00226     // If a drag hasn't started yet then return fail code.
00227     if (m_pStartSpread == NULL) return FALSE;
00228 
00229     // Copy the required information to the output parameters and return that a drga has
00230     // been started.
00231     if (ppStartSpread != NULL) *ppStartSpread = m_pStartSpread;
00232     if (pdcStartPos != NULL) *pdcStartPos = m_dcStartPos;
00233     return TRUE;
00234 }

BOOL OpDragBox::Init void   )  [static]
 

Initialises the OpDragBox base-class drag operation. Loads preferences.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/4/95
Returns:
TRUE if successful, FALSE if otherwise.

Reimplemented from SimpleCCObject.

Reimplemented in OpZoomIn, OpZoomOut, OpZoomTo100, OpZoomTo200, OpZoomTo300, and OpZoomTo400.

Definition at line 149 of file opdragbx.cpp.

00150 {
00151     return GetApplication()->DeclareSection(TEXT("Dragging"), 5) &&
00152            GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("DoSolidDragBoxes"),
00153                                          &m_fDoSolidDragBoxes, FALSE, TRUE);
00154 }

MILLIPOINT OpDragBox::Max MILLIPOINT  a,
MILLIPOINT  b
[inline, static, protected]
 

Helper function to return the largest of two ordinates.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/4/95

Definition at line 261 of file opdragbx.cpp.

00262 {
00263     return (a > b) ? a : b;
00264 }

MILLIPOINT OpDragBox::Min MILLIPOINT  a,
MILLIPOINT  b
[inline, static, protected]
 

Helper function to return the smallest of two ordinates.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/4/95

Definition at line 246 of file opdragbx.cpp.

00247 {
00248     return (a < b) ? a : b;
00249 }

BOOL OpDragBox::OnDragEnded Spread pBoxSpread,
const DocRect drDragBox,
ClickModifiers  cmods,
BOOL  fDragOK
[protected, virtual]
 

Reimplemented in OpZoom.

Definition at line 684 of file opdragbx.cpp.

00685 {
00686     return TRUE;
00687 }

BOOL OpDragBox::OnDragStarted Spread pStartSpread,
const DocCoord dcStartPos,
ClickModifiers  cmods
[protected, virtual]
 

Reimplemented in OpZoom.

Definition at line 608 of file opdragbx.cpp.

00609 {
00610     return TRUE;
00611 }

BOOL OpDragBox::OnPointerIdle Spread pBoxSpread,
const DocRect drDragBox,
ClickModifiers  cmods
[protected, virtual]
 

Definition at line 654 of file opdragbx.cpp.

00655 {
00656     return TRUE;
00657 }

BOOL OpDragBox::OnPointerMoved Spread pBoxSpread,
const DocRect drDragBox,
ClickModifiers  cmods
[protected, virtual]
 

Reimplemented in OpZoom.

Definition at line 631 of file opdragbx.cpp.

00632 {
00633     return TRUE;
00634 }

void OpDragBox::RenderDragBlobs DocRect  drClip,
Spread pSpread,
BOOL  bSolidDrag
[private, virtual]
 

Xors a rectangle onto the screen to mark out the size of the current drag box.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/4/05
Parameters:
drClip the clip rectangle to draw against [INPUTS] pSpread the spread containing the clip rectangle
See also:
OpDragBox::DrawXorRect

Reimplemented from Operation.

Definition at line 499 of file opdragbx.cpp.

00500 {
00501     DrawXorRect(drClip, pSpread, m_drLastDragBox);
00502 }

void OpDragBox::UpdateSolidDragBox const DocRect drNewDragBox  )  [private]
 

Calculates which rectangles to xor to change the last drawn solid drag box into the new solid drag box.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/4/95
Parameters:
drNewDragBox the new extent of the drag box, in the spread [INPUTS] coordinates of the spread where the drag started
See also:
OpDragBox::DragPointerMove; OpDragBox::UpdateUnfilledDragBox

Definition at line 330 of file opdragbx.cpp.

00331 {
00332     // Set up four update rectangles.  We will xor none, some, or all of these rectangles to
00333     // produce the new drag box.
00334     DocRect drUpdate[4];
00335     INT32 nHowMany;
00336 
00337     // Find the intersection of the last and new rectangles.  We will exclude this from
00338     // any xoring as it is already xored.
00339     DocRect drCommonDragBox = drNewDragBox.Intersection(m_drLastDragBox);
00340 
00341     // Calculate the rectangles that need to be xored to change the last into the new
00342     // drag box.  This depends on how they overlap.
00343     if (drCommonDragBox.IsEmpty())
00344     {
00345         // There's no intersection between the last drag box and the new drag box, even
00346         // though they share a common corner.  So xor the full extent of both drag rects.
00347         drUpdate[0] = m_drLastDragBox;
00348         drUpdate[1] = drNewDragBox;
00349         nHowMany = 2;
00350     }
00351     else if (drNewDragBox.ContainsRect(m_drLastDragBox))
00352     {
00353         // The new drag rect completely contains the last one, so clip out the last.
00354         nHowMany = ((DocRect&) drNewDragBox).SplitRect(m_drLastDragBox, drUpdate);
00355     }
00356     else if (m_drLastDragBox.ContainsRect(drNewDragBox))
00357     {
00358         // The last drag rect completely contains the new one, so clip out the new.
00359         nHowMany = m_drLastDragBox.SplitRect(drNewDragBox, drUpdate);
00360     }
00361     else
00362     {
00363         // The drag rectangles overlap but neither completely contains the other, so set
00364         // the xor rectangles to be each drag rectangle less the common drag rectangle.
00365         nHowMany = m_drLastDragBox.SplitRect(drCommonDragBox, &drUpdate[0]);
00366         nHowMany += ((DocRect&) drNewDragBox).SplitRect(drCommonDragBox, &drUpdate[nHowMany]);
00367     }
00368 
00369     // Sanity check.
00370     ERROR3IF(nHowMany < 0 || nHowMany > 4,
00371                 "Wrong number of split rects in OpDragBox::UpdateSolidDragBox\n");
00372 
00373     // Draw the xor rects.
00374     for (INT32 i = 0; i < nHowMany; i++)
00375     {
00376         DrawXorRect(drUpdate[i], m_pStartSpread, drUpdate[i]);
00377     }
00378 }

void OpDragBox::UpdateUnfilledDragBox const DocRect drNewDragBox  )  [private]
 

Calculates which rectangles to xor to change the last drawn solid drag box into the new solid drag box.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/4/95
Parameters:
drNewDragBox the new extent of the drag box, in the spread [INPUTS] coordinates of the spread where the drag started
See also:
OpDragBox::DragPointerMove; OpDragBox::UpdateSolidDragBox

Definition at line 394 of file opdragbx.cpp.

00395 {
00396     // Remove the old drag box.
00397     DrawXorRect(m_drLastDragBox, m_pStartSpread, m_drLastDragBox);
00398 
00399     // Draw the new drag box.
00400     DrawXorRect(drNewDragBox, m_pStartSpread, drNewDragBox);
00401 }


Member Data Documentation

DocCoord OpDragBox::m_dcStartPos [private]
 

Definition at line 218 of file opdragbx.h.

DocRect OpDragBox::m_drLastDragBox [private]
 

Definition at line 219 of file opdragbx.h.

BOOL OpDragBox::m_fDoSolidDragBoxes = FALSE [static, private]
 

Determines how the drag operation base-class draws a drag box. If FALSE then the "tranditional" unfilled xor rectangle with a certain line colour is drawn. If FALSE a filled ("solid") xor rectangle of a certain line and fill colour will be drawn. The default is FALSE.

Preference: DoSolidDragBoxes Section: Dragging

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> Range: FALSE or TRUE

Definition at line 222 of file opdragbx.h.

Spread* OpDragBox::m_pStartSpread [private]
 

Definition at line 217 of file opdragbx.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:57:59 2007 for Camelot by  doxygen 1.4.4