// $Id: regshape.cpp 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // Implementation of the Regular Shape tool /* */ #include "camtypes.h" #include "regshape.h" //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "blobs.h" #include "csrstack.h" //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "finfodlg.h" //#include "justin.h" //#include "markn.h" #include "nodershp.h" #include "oilfiles.h" #include "opnudge.h" #include "oprshape.h" #include "optsmsgs.h" //#include "peter.h" //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "rshapbar.h" //#include "simon.h" #include "shapeops.h" //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "viewrc.h" //#include "will2.h" DECLARE_SOURCE( "$Revision: 1282 $" ); CC_IMPLEMENT_MEMDUMP(QuickShapeBase, Tool_v1) CC_IMPLEMENT_MEMDUMP(QuickShapeTool, QuickShapeBase) CC_IMPLEMENT_DYNCREATE(QuickShapeBaseInfoBarOp, InformationBarOp) // Must come after the last CC_IMPLEMENT.. macro #define new CAM_DEBUG_NEW TCHAR* QuickShapeTool::FamilyName = _T("Shape Tools"); TCHAR* QuickShapeTool::ToolName = _T("QuickShape Tool"); TCHAR* QuickShapeTool::Purpose = _T("Regular Shape manipulation"); TCHAR* QuickShapeTool::Author = _T("Peter Arnold"); INT32 QuickShapeTool::CreationMode = OpNewRegShape::RADIUS; INT32 QuickShapeTool::NumSides = 6; BOOL QuickShapeTool::CreatePolygons = TRUE; BOOL QuickShapeTool::CreateStellated = FALSE; BOOL QuickShapeTool::CreateCurved = FALSE; /******************************************************************************************** > QuickShapeBase::QuickShapeBase() Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Purpose: Default Constructor. Other initialisation is done in QuickShapeBase::Init which is called by the Tool Manager SeeAlso: QuickShapeBase::Init ********************************************************************************************/ QuickShapeBase::QuickShapeBase() { pcCurrentCursor = NULL; OldDetermineSpread = NULL; pQuickShapeBaseInfoBarOp = NULL; EditFieldMode = QuickShapeBase::EDITF_CENTRE; } /******************************************************************************************** > QuickShapeBase::~QuickShapeBase() Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Purpose: Destructor (Virtual). Does nothing. ********************************************************************************************/ QuickShapeBase::~QuickShapeBase() { // Set the infobar,s pointer to us to NULL as we are expiring pQuickShapeBaseInfoBarOp->pQuickShapeBase = NULL; } /******************************************************************************************** > BOOL QuickShapeBase::Init() Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Returns: FALSE if it does not want to be created, TRUE otherwise Purpose: Used to finish construction and to check if the Tool was properly constructed. Errors: ERROR2's if the resource file or the bar could not be found/opened/read SeeAlso: QuickShapeBase::QuickShapeBase ********************************************************************************************/ BOOL QuickShapeBase::Init() { // Declare all your ops here and only succeed if all declarations succeed BOOL ok = OpNewRegShape::Declare(); // This section reads in the infobar definition and creates an instance of // QuickShapeBaseInfoBarOp. Also pQuickShapeBaseInfoBarOp, the ptr to the tool's infobar, is set up // after the infobar is successfully read and created. if (ok) { pQuickShapeBaseInfoBarOp = new QuickShapeBaseInfoBarOp(this, _R(IDD_REGSHAPETOOLBAR)); ok=(pQuickShapeBaseInfoBarOp!=NULL); PORTNOTE("dialog", "Removed Bar reading") #if 0 CCResTextFile file; // Resource File QuickShapeBaseInfoBarOpCreate BarCreate; // Object that creates QuickShapeBaseInfoBarOp objects ok = file.open(_R(IDM_REGSHAPE_BAR), _R(IDT_INFO_BAR_RES)); // Open resource if (ok) ok = DialogBarOp::ReadBarsFromFile(file,BarCreate); // Read and create info bar if (ok) file.close(); // Close resource ERROR2IF(!ok,FALSE,"Unable to load RegShBar.ini from resource"); // Info bar now exists. Now get a pointer to it String_32 str(_R(IDS_REGSHAPE_INFOBARNAME)); DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str); ERROR2IF(pDialogBarOp==NULL, FALSE, "infobar not found\n"); ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(QuickShapeBaseInfoBarOp)); if (ok) { pQuickShapeBaseInfoBarOp = (QuickShapeBaseInfoBarOp*)pDialogBarOp; pQuickShapeBaseInfoBarOp->pQuickShapeBase = this; } #endif ERROR2IF(!ok,FALSE,"Error finding the RegShape tool info bar"); } return (ok); } /******************************************************************************************** > virtual void QuickShapeBase::SelectChange(BOOL isSelected) Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Inputs: isSelected - TRUE = tool has been selected - FALSE = tool has been deselected Outputs: - Returns: - Purpose: Starts up and closes down the RegShape tool SeeAlso: - ********************************************************************************************/ void QuickShapeBase::SelectChange(BOOL isSelected) { if (isSelected) { if (!CreateCursors()) return; CurrentCursorID = CursorStack::GPush(pcNormalCursor, FALSE); // Push cursor but don't display now pcCurrentCursor = pcNormalCursor; // Create and display the tool's info bar pQuickShapeBaseInfoBarOp->Create(); pQuickShapeBaseInfoBarOp->SetCreationMode(GetCreationMode()); pQuickShapeBaseInfoBarOp->SetHelp(); // Say which blobs to display BlobManager* BlobMgr = GetApplication()->GetBlobManager(); if (BlobMgr != NULL) { // Decide which blobs we will display BlobStyle MyBlobs; MyBlobs.Object = TRUE; // Tell the blob manager BlobMgr->ToolInterest(MyBlobs); } } else { // Deselection - destroy the tool's cursors, if they exist. if (pcCurrentCursor != NULL) { CursorStack::GPop(CurrentCursorID); CurrentCursorID = 0; pcCurrentCursor = NULL; } DestroyCursors(); // Remove the info bar from view by deleting the actual underlying window pQuickShapeBaseInfoBarOp->Delete(); } // ensure any tool object blobs are removed. BlobManager* BlobMgr = GetApplication()->GetBlobManager(); if (BlobMgr != NULL) { BlobStyle bsRemoves; bsRemoves.ToolObject = TRUE; BlobMgr->RemoveInterest(bsRemoves); } } /******************************************************************************************** > BOOL QuickShapeBase::CreateCursors() Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Inputs: - Outputs: - Returns: TRUE if all the RegShape tool cursors have been successfully created Purpose: Creates all the RegShape tool cursors SeeAlso: - ********************************************************************************************/ BOOL QuickShapeBase::CreateCursors() { // This tool has just been selected. Create the cursors. pcNormalCursor = new Cursor(this, GetCursorID()); pcBlobCursor = new Cursor(this, _R(IDC_MOVEBEZIERCURSOR)); pcEdgeCursor = new Cursor(this, _R(IDC_RESHAPECURSOR)); if ( pcNormalCursor==NULL || !pcNormalCursor->IsValid() || pcEdgeCursor==NULL || !pcEdgeCursor->IsValid() || pcBlobCursor==NULL || !pcBlobCursor->IsValid() ) { DestroyCursors(); return FALSE; } else return TRUE; } /******************************************************************************************** > void QuickShapeBase::DestroyCursors() Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Inputs: - Outputs: - Returns: - Purpose: Destroys all the RegShape tool cursors SeeAlso: - ********************************************************************************************/ void QuickShapeBase::DestroyCursors() { if (pcNormalCursor != NULL) delete pcNormalCursor; if (pcEdgeCursor != NULL) delete pcEdgeCursor; if (pcBlobCursor != NULL) delete pcBlobCursor; pcNormalCursor = NULL; pcBlobCursor = NULL; pcEdgeCursor = NULL; } /******************************************************************************************** > void QuickShapeBase::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods, Spread* pSpread ) Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Inputs: PointerPos - The DocCoord of the point where the mouse button was clicked Click - Describes the type of click that was detected. ClickMods - Indicates which buttons caused the click and which modifers were pressed at the same time pSpread - The spread in which the click happened Returns: - Purpose: To handle a Mouse Click event for the RegShape Tool. SeeAlso: Tool::MouseClick; ClickType; ClickModifiers ********************************************************************************************/ void QuickShapeBase::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods, Spread* pSpread ) { if (ClickMods.Menu) return; // Don't do anything if the user clicked the Menu button NodeRegularShape* HitShape = NULL; ShapeClickEffect TestEffect = DetermineClickEffect(PointerPos, pSpread, &HitShape); // Get the infobar into the right mode so immediate drags are shown EditModeIDS NewMode; switch (TestEffect) { case SHAPECLICK_CENTRE: NewMode = EDITF_CENTRE; break; case SHAPECLICK_PRIMARY: NewMode = EDITF_MAJOR; break; case SHAPECLICK_ELLIPSE: case SHAPECLICK_RECTANGLE: NewMode = EDITF_SIZE; break; case SHAPECLICK_STELLATION: NewMode = EDITF_STELLATION; break; case SHAPECLICK_PRIMARYCURVE: case SHAPECLICK_STELLATIONCURVE: NewMode = EDITF_CURVE; break; default: NewMode = EditFieldMode; } if (NewMode != EditFieldMode) { EditFieldMode = NewMode; GetInfoBar()->BuildEditMenu(TRUE); } // If we have found a shape then pass the click onto the shape for it to deal with if (HitShape != NULL) { if (DoesPolygonExist()) HitShape->OnToolClick(PointerPos, Click, ClickMods, pSpread); else HitShape->OnClick(PointerPos, Click, ClickMods, pSpread); } else { // call the base class .... DragTool::OnClick (PointerPos, Click, ClickMods, pSpread); } // Alternativly, Deal with creating new shapes if ( (HitShape == NULL) && (Click == CLICKTYPE_DRAG) ) { // Just what we wanted - Someone is dragging the mouse about // We need to make an operation to perform the drag with OpNewRegShape* pOpNewRegShape = new OpNewRegShape; if (pOpNewRegShape == NULL) { // Inform the person doing the clicking that life is not looking so good InformError(); } else { // Put the edit field into size mode EditModeIDS NewMode = EDITF_MAJOR; if (IsEllipse() || IsRectangle()) NewMode = EDITF_SIZE; if (NewMode != EditFieldMode) { EditFieldMode = NewMode; GetInfoBar()->BuildEditMenu(TRUE); } // Start the drag operation and pass in the Anchor INT32 NumberOfSides = GetNumSides(); OpNewRegShape::CreateMode CreateMode = (OpNewRegShape::CreateMode)GetCreationMode(); BOOL PolyGone = !GetPolygon(); BOOL Stellation = GetStellation(); BOOL Curvature = GetCurved(); // Possibly use the current infobar settings if (AttributeManager::LastAttrAppliedBecomesCurrent && !IsEllipse()) { if (!IsRectangle()) { NumberOfSides = pQuickShapeBaseInfoBarOp->GetNumSides(FALSE); if (NumberOfSides < 3) NumberOfSides = GetNumSides(); PolyGone = !pQuickShapeBaseInfoBarOp->IsPolygonCreate(); Stellation = pQuickShapeBaseInfoBarOp->IsStellationCreate(); } Curvature = pQuickShapeBaseInfoBarOp->IsCurvedCreate(); } pOpNewRegShape->DoDrag( pSpread, PointerPos, NumberOfSides, CreateMode, PolyGone, Stellation, Curvature); DialogBarOp::SetSystemStateChanged(); } } } /******************************************************************************************** > void QuickShapeBase::OnMouseMove( DocCoord PointerPos,Spread* pSpread, ClickModifiers ClickMod ) Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Inputs: PointerPos - The DocCoord of the point where the mouse has moved to pSpread - The spread in which the move occurred ClickMods - The state of the various modifiers at the time of the mouse move Returns: TRUE if it handled the Click, FALSE otherwise Purpose: To handle a Mouse Move event for the RegShape Tool. SeeAlso: Tool::MouseClick; ClickType; ClickModifiers ********************************************************************************************/ void QuickShapeBase::OnMouseMove(DocCoord PointerPos,Spread* pSpread,ClickModifiers ClickMods) { // If we're over a blob then show the move blob cursor NodeRegularShape* HitShape; ShapeClickEffect TestEffect = DetermineClickEffect(PointerPos, pSpread, &HitShape); Cursor* DisplayCur = pcNormalCursor; if (TestEffect != SHAPECLICK_NONE) DisplayCur = pcBlobCursor; if ( ((TestEffect == SHAPECLICK_EDGE1) || (TestEffect == SHAPECLICK_EDGE2)) && !HitShape->IsCircular()) DisplayCur = pcEdgeCursor; if ( (DisplayCur != pcCurrentCursor) && (DisplayCur != NULL) ) { pcCurrentCursor = DisplayCur; CursorStack::GSetTop(pcCurrentCursor, CurrentCursorID); } // Display status line help text for the current position DisplayStatusBarHelp(PointerPos, pSpread, ClickMods); } /******************************************************************************************** > void QuickShapeBase::DisplayStatusBarHelp(DocCoord DocPos, Spread* pSpread, ClickModifiers ClickMods) Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Inputs: Point, Spread and click modifiers Outputs: - Returns: - Purpose: Displays status help string for the given position in the status bar SeeAlso: QuickShapeBase::GetCurrentStatusLineText ********************************************************************************************/ void QuickShapeBase::DisplayStatusBarHelp(DocCoord DocPos, Spread* pSpread, ClickModifiers ClickMods) { String_256 StatusMsg(""); GetCurrentStatusLineText(&StatusMsg, pSpread, DocPos, ClickMods); GetApplication()->UpdateStatusBarText(&StatusMsg); } /******************************************************************************************** > virtual BOOL QuickShapeBase::GetStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods) Author: Peter_Arnold (Xara Group Ltd) Created: 12/12/94 Inputs: pSpread points to a spread DocPos points to a point in a document ClickMods are the current click modifiers Outputs: Updates the string in ptext Returns: TRUE Purpose: Returns the current status line help string SeeAlso: QuickShapeBase::GetCurrentStatusLineText ********************************************************************************************/ BOOL QuickShapeBase::GetStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods) { GetCurrentStatusLineText(ptext, pSpread, DocPos, ClickMods); return TRUE; } /******************************************************************************************** > void QuickShapeBase::GetCurrentStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods) Author: Peter_Arnold (Xara Group Ltd) Created: 12/12/94 Inputs: pSpread points to a spread DocPos points to a point in a document ClickMods are the current click modifiers Outputs: Updates the string in ptext Returns: - Purpose: QuickShapeBase::GetStatusLineText ********************************************************************************************/ void QuickShapeBase::GetCurrentStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods) { NodeRegularShape* pShape; switch (DetermineClickEffect(DocPos, pSpread, &pShape)) { case SHAPECLICK_NONE: ExpandShapeString(ptext, _R(IDS_REGSHAPETOOL_CREATENEW), TRUE); break; case SHAPECLICK_RECTANGLE: case SHAPECLICK_PRIMARY: { String_32 shape; if (pShape->IsPrimaryCurvature() || pShape->IsStellationCurvature()) shape.Load(_R(IDS_REGSHAPETOOL_RCURVE)); else shape.Load(_R(IDS_REGSHAPETOOL_ACURVE)); ptext->MakeMsg(_R(IDS_REGSHAPETOOL_DRAGPVERTEX), (TCHAR*)shape); break; } case SHAPECLICK_ELLIPSE: { ptext->Load(_R(IDS_REGSHAPETOOL_DRAGELLIPSE)); break; } case SHAPECLICK_STELLATION: { String_32 shape; if (pShape->IsPrimaryCurvature() || pShape->IsStellationCurvature()) shape.Load(_R(IDS_REGSHAPETOOL_RCURVE)); else shape.Load(_R(IDS_REGSHAPETOOL_ACURVE)); ptext->MakeMsg(_R(IDS_REGSHAPETOOL_DRAGSVERTEX), (TCHAR*)shape); break; } case SHAPECLICK_PRIMARYCURVE: case SHAPECLICK_STELLATIONCURVE: ptext->Load(_R(IDS_REGSHAPETOOL_DRAGCURVE)); break; case SHAPECLICK_CENTRE: { String_32 shape; if (pShape->IsCircular()) shape.Load(_R(IDS_REGSHAPETOOL_SPOLYGON)); else shape.Load(_R(IDS_REGSHAPETOOL_SELLIPSE)); ptext->MakeMsg(_R(IDS_REGSHAPETOOL_DRAGCENTRE), (TCHAR*)shape); break; } case SHAPECLICK_EDGE1: case SHAPECLICK_EDGE2: { String_32 extra; INT32 ID; if (pShape->IsCircular()) ID = _R(IDS_REGSHAPETOOL_DRAGEDGE1); else ID = _R(IDS_REGSHAPETOOL_DRAGEDGE2); if (pShape->IsStellated()) extra.Load(_R(IDS_REGSHAPETOOL_RSTELL)); else extra.Load(_R(IDS_REGSHAPETOOL_SSTELL)); ptext->MakeMsg(ID, (TCHAR*)extra); break; } default: break; } } /******************************************************************************************* > void QuickShapeBase::ExpandShapeString(StringBase* pString, INT32 StringID, BOOL Singular) Author: Peter_Arnold (Xara Group Ltd) Created: 29/03/95 Inputs: pString - points to the string to store the expanded result in Singular - TRUE/FALSE for singular/plural StringID - the resource ID of the string to expand Outputs: pString will be expanded to hold the name of the QuickShape being edited Returns: - Purpose: Insert the name of the QuickShape the tool is currently creating into position in the string Errors: - SeeAlso: - ********************************************************************************************/ void QuickShapeBase::ExpandShapeString(StringBase* pString, INT32 StringID, BOOL Singular) { String_32 Name; if (Singular) Name.Load(GetShapeID()); else Name.Load(GetShapesID()); pString->MakeMsg(StringID, (TCHAR*)Name); } /******************************************************************************************* > ShapeClickEffect QuickShapeBase::DetermineClickEffect(DocCoord PointerPos, Spread* pSpread, NodeRegularShape** ReturnShape = NULL) Author: Peter_Arnold (Xara Group Ltd) Created: 12/12/94 Inputs: PointerPos is the mouse position pSpread is a pointer to the spread containing the mouse position Outputs: ReturnShape returns a pointer to the shape the mouse would click on (NULL is returned if there is no excited shape) Returns: The effect of clicking. Purpose: Used when the cursor moves and when single clicking. This routine determines what effect a click will have by looking at the object under the pointer. The last position and result is cached so we can avoid excessive document scans Errors: ERROR2 if there is no current DocView SeeAlso: ShapeClickEffect ********************************************************************************************/ ShapeClickEffect QuickShapeBase::DetermineClickEffect(DocCoord PointerPos, Spread* pSpread, NodeRegularShape** ReturnShape) { // // See if we can supply the result from the cache. // if ((OldDeterminePos == PointerPos) && (OldDetermineSpread == pSpread) && IsInterestingShape(OldDetermineShape)) // { // *ReturnShape = OldDetermineShape; // return OldDetermineResult; // } OldDeterminePos = PointerPos; OldDetermineSpread = pSpread; ShapeClickEffect WhatToDo = SHAPECLICK_NONE; // Scan through the selected shapes, and see if any of them want the click DocRect BlobRect; DocView* pDocView = DocView::GetCurrent(); ERROR2IF( pDocView==NULL, WhatToDo, "QuickShapeBase::DetermineClickEffect: Can't find current DocView"); // Find the selected range of objects SelRange* Selected = GetApplication()->FindSelection(); Node* pNode = Selected->FindFirst(); while (pNode != NULL) { if (IS_A(pNode, NodeRegularShape) && IsInterestingShape((NodeRegularShape*)pNode)) { NodeRegularShape* CurrentHit = (NodeRegularShape*) pNode; INT32 ClickPointNumber; WhatToDo = CurrentHit->DetermineClickEffect(&PointerPos, pSpread, &ClickPointNumber); // Ignore edge reforming if the tool shouldn't do it if ( ( (WhatToDo == SHAPECLICK_EDGE1) || (WhatToDo == SHAPECLICK_EDGE2) ) && !CanReformEdges()) WhatToDo = SHAPECLICK_NONE; if (WhatToDo != SHAPECLICK_NONE) { if (ReturnShape != NULL) *ReturnShape = CurrentHit; OldDetermineShape = CurrentHit; return (OldDetermineResult = WhatToDo); } } // Now find the next selected node pNode = Selected->FindNext(pNode); } // Didn't find anything if (ReturnShape != NULL) *ReturnShape = NULL; OldDetermineShape = NULL; return (OldDetermineResult = SHAPECLICK_NONE); } /******************************************************************************************** > MsgResult QuickShapeBaseInfoBarOp::Message(Msg* Message) Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Inputs: Msg = The message to handle Outputs: - Returns: - Purpose: RegShape info bar message handler Errors: - SeeAlso: QuickShapeBaseInfoBarOp::DialogMessage ********************************************************************************************/ MsgResult QuickShapeBaseInfoBarOp::Message(Msg* Message) { BOOL UpdateInfo = FALSE; if (IS_OUR_DIALOG_MSG(Message)) { MsgResult Result = DialogMessage((DialogMsg*)Message); if (Result != OK) return Result; } else if (MESSAGE_IS_A(Message,OpMsg)) // Update the bar after an operation has finished { if ( ((OpMsg*)Message)->MsgType == OpMsg::END) UpdateInfo = TRUE; } else if (MESSAGE_IS_A(Message,UnitMsg)) // Update the bar as someone has changd a unit { UpdateInfo = TRUE; } else if (MESSAGE_IS_A(Message, OptionsChangingMsg)) // Or a units-changing message? { if (((OptionsChangingMsg*)Message)->State == OptionsChangingMsg::NEWUNITS) UpdateInfo = TRUE; } else if (MESSAGE_IS_A(Message,SelChangingMsg)) // Update the bar after the selection has changed { if ( ((SelChangingMsg*)Message)->State == SelChangingMsg::SELECTIONCHANGED) UpdateInfo = TRUE; } else if (MESSAGE_IS_A(Message,DocChangingMsg)) // Update the bar after an operation has finished { if ( ((DocChangingMsg*)Message)->State == DocChangingMsg::SELCHANGED) UpdateInfo = TRUE; } else if (MESSAGE_IS_A(Message,ShapeEditedMsg)) // Update the bar during shape drag { UpdateEditFields(((ShapeEditedMsg*)Message)->pShape, ((ShapeEditedMsg*)Message)->pSpread); } if (UpdateInfo) { UpdateInfobar(); BuildEditMenu(); } // Pass the message on to our parent class return (InformationBarOp::Message(Message)); } /******************************************************************************************** > MsgResult QuickShapeBaseInfoBarOp::DialogMessage(DialogMsg* Msg) Author: Peter_Arnold (Xara Group Ltd) Created: 18/8/95 Inputs: Msg = The message to handle Outputs: - Returns: Message Result Purpose: RegShape info bar dialog message handler (deals with dialog specifc messages) Errors: - SeeAlso: QuickShapeBaseInfoBarOp::Message ********************************************************************************************/ MsgResult QuickShapeBaseInfoBarOp::DialogMessage(DialogMsg* Msg) { Path NewPath; // Check if the message is a CANCEL if (Msg->DlgMsg == DIM_CANCEL) { Close(); // Close the dialog } else if (Msg->DlgMsg == DIM_CREATE) { InitialiseInfobar(); } else { BOOL CauseShapeEdit = FALSE; EditRegularShapeParam ChangeData(NULL); if (pQuickShapeBase!=NULL) ChangeData.ShapesToAffect = (EditRegularShapeParam::AffectShape)pQuickShapeBase->GetShapesToAffect(); if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_RADIUS)) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL) { pQuickShapeBase->SetCreationMode(OpNewRegShape::RADIUS); SetCreationMode(OpNewRegShape::RADIUS); } } else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_DIAMETER)) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL) { pQuickShapeBase->SetCreationMode(OpNewRegShape::DIAMETER); SetCreationMode(OpNewRegShape::DIAMETER); } } else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_BOUNDBOX)) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL) { pQuickShapeBase->SetCreationMode(OpNewRegShape::BOUNDS); SetCreationMode(OpNewRegShape::BOUNDS); } } else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_STELLATION)) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL) { BOOL NewStellSetting = IsStellationCreate(); pQuickShapeBase->SetStellation(NewStellSetting); // Pop the button out as the bitmap buttons are stupid if (!NewStellSetting) { SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_STELLATION), FALSE); } if (ChangeMode) { // Set the operation parameters if (NewStellSetting) ChangeData.NewStellated = EditRegularShapeParam::CHANGE_SETTRUE; else ChangeData.NewStellated = EditRegularShapeParam::CHANGE_SETFALSE; CauseShapeEdit = TRUE; } } } else if (Msg->GadgetID ==_R(IDC_BTN_REGSHAPETOOL_CURVATURE)) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL) { BOOL NewCurveSetting = IsCurvedCreate(); pQuickShapeBase->SetCurved(NewCurveSetting); // Pop the button out as the bitmap buttons are stupid if (!NewCurveSetting) { SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), FALSE); } if (ChangeMode) { // Set the operation parameters if (NewCurveSetting) { ChangeData.NewPrimaryCurvature = EditRegularShapeParam::CHANGE_SETTRUE; ChangeData.NewStellationCurvature = EditRegularShapeParam::CHANGE_SETTRUE; } else { ChangeData.NewPrimaryCurvature = EditRegularShapeParam::CHANGE_SETFALSE; ChangeData.NewStellationCurvature = EditRegularShapeParam::CHANGE_SETFALSE; } CauseShapeEdit = TRUE; } } } else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_POLYGON)) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL) { pQuickShapeBase->SetPolygon(TRUE); if (ChangeMode) { // Set the operation parameters ChangeData.NewCircular = EditRegularShapeParam::CHANGE_SETFALSE; CauseShapeEdit = TRUE; } else { SetPolygonCreate(TRUE); } } } else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_ELLIPSE)) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED && pQuickShapeBase!=NULL) { pQuickShapeBase->SetPolygon(FALSE); if (ChangeMode) { // Set the operation parameters ChangeData.NewCircular = EditRegularShapeParam::CHANGE_SETTRUE; CauseShapeEdit = TRUE; } else { SetPolygonCreate(FALSE); } } } else if (Msg->GadgetID == _R(IDC_BTN_REGSHAPETOOL_LINES)) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED) { NewPath.Initialise(4,1); NewPath.AddMoveTo(DocCoord(0,0)); NewPath.AddLineTo(DocCoord(72000,0)); ChangeData.NewEdgePath1 = &NewPath; ChangeData.NewEdgePath2 = &NewPath; CauseShapeEdit = TRUE; } } else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_BUMPLEFT)) { if (IsEnabled(_R(IDC_EDIT_REGSHAPETOOL_BUMPLEFT))) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED) { if (!BumpLeft()) InformError(); } else if (Msg->DlgMsg == DIM_LFT_BN_UP) { if (!EditCommit(TRUE)) InformError(); UpdateEditFields(); } } } else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_BUMPRIGHT)) { if (IsEnabled(_R(IDC_EDIT_REGSHAPETOOL_BUMPRIGHT))) { if (Msg->DlgMsg==DIM_LFT_BN_CLICKED) { if (!BumpRight()) InformError(); } else if (Msg->DlgMsg == DIM_LFT_BN_UP) { if (!EditCommit(TRUE)) InformError(); UpdateEditFields(); } } } else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_BUMPUP)) { if (IsEnabled(_R(IDC_EDIT_REGSHAPETOOL_BUMPUP))) { if (Msg->DlgMsg == DIM_LFT_BN_CLICKED) { if (!BumpUp()) InformError(); } else if (Msg->DlgMsg == DIM_LFT_BN_UP) { if (!EditCommit(FALSE)) InformError(); UpdateEditFields(); } } } else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_BUMPDOWN)) { if (IsEnabled(_R(IDC_EDIT_REGSHAPETOOL_BUMPDOWN))) { if (Msg->DlgMsg == DIM_LFT_BN_CLICKED) { if (!BumpDown()) InformError(); } else if (Msg->DlgMsg == DIM_LFT_BN_UP) { if (!EditCommit(FALSE)) InformError(); UpdateEditFields(); } } } // Number of sides edit/drop down box else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_SIDES)) { if (Msg->DlgMsg==DIM_SELECTION_CHANGED && pQuickShapeBase!=NULL) { INT32 NewNumSides = GetNumSides(TRUE); if (NewNumSides != -1) { pQuickShapeBase->SetNumSides(NewNumSides); if (ChangeMode) { // Set the operation parameters ChangeData.NewNumSides = NewNumSides; CauseShapeEdit = TRUE; } } } else if (Msg->DlgMsg== DIM_TEXT_CHANGED && pQuickShapeBase!=NULL) { BOOL Valid; String_256 string = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES),&Valid); if (!string.IsEmpty()) { pQuickShapeBase->SetNumSides(GetLongGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES), 1, 99, 0, &Valid)); if (!Valid) { InformError(_R(IDE_REGSHAPETOOL_SIDES)); pQuickShapeBase->SetNumSides(3); UpdateInfobar(); } } } } else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_POS)) { if (Msg->DlgMsg==DIM_SELECTION_CHANGED && pQuickShapeBase!=NULL) { WORD temp; GetValueIndex(_R(IDC_EDIT_REGSHAPETOOL_POS), &temp); pQuickShapeBase->EditFieldMode = pQuickShapeBase->EditFieldOptions[temp]; UpdateEditFields(); } } else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_UPPER)) { if (Msg->DlgMsg == DIM_SELECTION_CHANGED) { if (!EditCommit(TRUE)) InformError(); UpdateEditFields(); } } else if (Msg->GadgetID == _R(IDC_EDIT_REGSHAPETOOL_LOWER)) { if (Msg->DlgMsg == DIM_SELECTION_CHANGED) { if (!EditCommit(FALSE)) InformError(); UpdateEditFields(); } } // Invoke an operation to perform changes, if requested if (CauseShapeEdit) { OpDescriptor* Apple = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpEditRegularShape)); if (Apple != NULL) Apple->Invoke(&ChangeData); } } return OK; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::InitialiseInfobar() Author: Peter_Arnold (Xara Group Ltd) Created: 21/11/94 Inputs: - Outputs: - Returns: TRUE if all went OK, otherwise FALSE Purpose: To initialise the regular shape tool's infobar. In particular it sets up the number of sides listbox, and puts the buttons into a sensible default state. Errors: - SeeAlso: - ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::InitialiseInfobar() { if (WindowID==NULL || pQuickShapeBase==NULL) return TRUE; // build the list for the number of sides menu if (pQuickShapeBase->DoesNumSidesExist()) { String_32 Str; for (INT32 i = 3; i <= 10; i++) { Str._MakeMsg(_T("#1%d"),i); SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES),Str); } SetComboListLength(_R(IDC_EDIT_REGSHAPETOOL_SIDES)); SetNumSides(pQuickShapeBase->GetNumSides()); PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_SIDES)); } PreviousCurvature = FALSE; PreviousStellation = FALSE; PreviousCircular = FALSE; BuildEditMenu(TRUE); UpdateInfobar(); return TRUE; } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::BuildEditMenu(BOOL UpdateImmediate = FALSE) Author: Peter_Arnold (Xara Group Ltd) Created: 10/1/95 Inputs: UpdateImmediate TRUE if the menu should be forced to redraw Outputs: - Returns: - Purpose: Builds the list-box menu for the the edit fields. The contents of the menu are dependent on the currenty selected shapes (whether or not thay have curvature) Errors: - SeeAlso: - ********************************************************************************************/ void QuickShapeBaseInfoBarOp::BuildEditMenu(BOOL UpdateImmediate) { if (WindowID==NULL || pQuickShapeBase==NULL) return; BOOL HasCurvature = FALSE; BOOL HasStellation = FALSE; BOOL JustCircular = TRUE; // scan the selected shapes to see if any have curvature SelRange* Selection = GetApplication()->FindSelection(); Node* pNode = Selection->FindFirst(); while ((pNode != NULL) && !(HasCurvature && HasStellation)) { if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode)) { NodeRegularShape* pShape = (NodeRegularShape*)pNode; if (pShape->IsPrimaryCurvature() || pShape->IsStellationCurvature()) HasCurvature = TRUE; if (pShape->IsStellated()) HasStellation = TRUE; if (!pShape->IsCircular()) JustCircular = FALSE; } pNode = Selection->FindNext(pNode); } if (JustCircular) { HasCurvature = HasStellation = FALSE; } // Re-build the drop down menu if ((PreviousCurvature != HasCurvature) || (PreviousStellation != HasStellation) || (PreviousCircular != JustCircular) || UpdateImmediate) { PreviousCircular = JustCircular; PreviousCurvature = HasCurvature; PreviousStellation = HasStellation; String_32 Str; const INT32 MenuEntries = 4; BOOL ResPresent[MenuEntries] = {TRUE, TRUE, HasStellation, HasCurvature}; UINT32 ResIDs[MenuEntries] = {_R(IDS_REGSHAPETOOL_MENUCENTRE), _R(IDS_REGSHAPETOOL_MENUMAJOR), _R(IDS_REGSHAPETOOL_MENUSTELL), _R(IDS_REGSHAPETOOL_MENUCURVE)}; QuickShapeBase::EditModeIDS OptionIDs[MenuEntries] = {QuickShapeBase::EDITF_CENTRE, QuickShapeBase::EDITF_MAJOR, QuickShapeBase::EDITF_STELLATION, QuickShapeBase::EDITF_CURVE}; // By hiding and showing the gadget it forces closed an open drop-down list HideGadget(_R(IDC_EDIT_REGSHAPETOOL_POS), TRUE); DeleteAllValues(_R(IDC_EDIT_REGSHAPETOOL_POS)); HideGadget(_R(IDC_EDIT_REGSHAPETOOL_POS), FALSE); // Fill in the standard menu options INT32 CurrentCount = 0; for (INT32 i = 0; i < MenuEntries; i++) { if (ResPresent[i]) { // Get the string and set the option name to it UINT32 StringResource = ResIDs[i]; if ((i == 1) && (pQuickShapeBase->IsEllipse() || pQuickShapeBase->IsRectangle())) { StringResource = _R(IDS_REGSHAPETOOL_MENUSIZE); pQuickShapeBase->EditFieldOptions[CurrentCount++] = QuickShapeBase::EDITF_SIZE; } else pQuickShapeBase->EditFieldOptions[CurrentCount++] = OptionIDs[i]; Str.MakeMsg(StringResource); SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_POS),Str); } } // Ellipse and Rectangle tools have special rotate option if (pQuickShapeBase->IsEllipse() || pQuickShapeBase->IsRectangle()) { Str.MakeMsg(_R(IDS_REGSHAPETOOL_MENUROT)); pQuickShapeBase->EditFieldOptions[CurrentCount++] = QuickShapeBase::EDITF_ROT; SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_POS),Str); } SetComboListLength(_R(IDC_EDIT_REGSHAPETOOL_POS)); // Ensure that the selected mode is valid for this particular tool if ((!HasCurvature && (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_CURVE)) || (!HasStellation && (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_STELLATION)) ) { pQuickShapeBase->EditFieldMode = QuickShapeBase::EDITF_CENTRE; } if (!pQuickShapeBase->IsEllipse() && !pQuickShapeBase->IsRectangle() && ((pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_SIZE) || (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_ROT))) { pQuickShapeBase->EditFieldMode = QuickShapeBase::EDITF_MAJOR; } INT32 SelectedItem = (INT32)pQuickShapeBase->EditFieldMode; if (SelectedItem == 3) { if (!HasStellation) SelectedItem = 2; } if (SelectedItem == (INT32)(QuickShapeBase::EDITF_SIZE)) SelectedItem = 1; if (SelectedItem == (INT32)(QuickShapeBase::EDITF_ROT)) { if (HasCurvature) SelectedItem = 3; else SelectedItem = 2; } SetSelectedValueIndex(_R(IDC_EDIT_REGSHAPETOOL_POS),SelectedItem); PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_POS)); } UpdateEditFields(); } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::UpdateEditFields(NodeRegularShape* ShapeToShow = NULL, Spread* ShapeSpread = NULL) Author: Peter_Arnold (Xara Group Ltd) Created: 17/1/95 Inputs: ShapeToShow - the shape to show in the edit fields (NULL to scan the doc) ShapeSpread - the spread containing ShapeToShow Outputs: - Returns: - Purpose: Updates the edit fields. The contents depend on the currently selected menu item. Errors: - SeeAlso: - ********************************************************************************************/ void QuickShapeBaseInfoBarOp::UpdateEditFields(NodeRegularShape* ShapeToShow, Spread* ShapeSpread) { if (WindowID==NULL || pQuickShapeBase==NULL) return; BOOL NoneSelected = TRUE; BOOL MultipleCentres = FALSE; DocCoord Centre(-1,-1); BOOL MultipleMajorRadius = FALSE; BOOL MultipleMinorRadius = FALSE; BOOL MultipleMajorAngle = FALSE; double MajorRadius = -1.0; double MinorRadius = -1.0; double MajorAngle = -1.0; BOOL MultipleStellationRadius = FALSE; BOOL MultipleStellationOffset = FALSE; double StellationRadius = -1.0; double StellationOffset = -1000.0; UINT32 PreviousNumSides = 0; BOOL MultiplePrimaryCurvature = FALSE; BOOL MultipleStellationCurvature = FALSE; double PrimaryCurvature = -1.0; double StellationCurvature = -1.0; BOOL FoundStellatedCurve = FALSE; // scan the selected shapes for things to display in the edit fields SelRange* Selection = GetApplication()->FindSelection(); Node* pNode = Selection->FindFirst(); if (ShapeToShow != NULL) pNode = ShapeToShow; while (pNode != NULL) { if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode)) { NodeRegularShape* pShape = (NodeRegularShape*)pNode; if (ShapeToShow == NULL) CurrentSpread = pShape->FindParentSpread(); else CurrentSpread = ShapeSpread; NoneSelected = FALSE; // Test centres if (!MultipleCentres) { if (Centre == DocCoord(-1,-1)) { Centre = pShape->GetCentrePoint(); } else { if (Centre != pShape->GetCentrePoint()) MultipleCentres = TRUE; } } // Test major axes radi if (!MultipleMajorRadius) { double Length = pShape->GetCentrePoint().Distance(pShape->GetMajorAxes()); Length = Length*2; // Make it the diameter, not the radius if (MajorRadius == -1.0) { MajorRadius = Length; } else { if (Length != MajorRadius) MultipleMajorRadius = TRUE; } } // Test minor axes radi if (!MultipleMinorRadius) { double Length = pShape->GetCentrePoint().Distance(pShape->GetMinorAxes()); Length = Length*2; // Make it the diameter, not the radius if (MinorRadius == -1.0) { MinorRadius = Length; } else { if (Length != MinorRadius) MultipleMinorRadius = TRUE; } } // Test major axes angle if (!MultipleMajorAngle) { double Angle = pShape->GetRotationAngle(); if (MajorAngle == -1.0) { MajorAngle = Angle; } else { // we are subject to NASTY rounding errors here !!!! // previously this said *1000; but this was too accurate and would incorrectly // state many when on-screen the shapes all appear to be (e.g. 45 degrees). // the problem is to do with the way that GetRotationAngle () does its stuff if ((INT32)(Angle*100) != (INT32)(MajorAngle*100)) MultipleMajorAngle = TRUE; } } if (!pShape->IsCircular()) { // Test stellation radi if (!MultipleStellationRadius) { double Length = pShape->GetCentrePoint().Distance(pShape->GetMajorAxes()); Length = Length * pShape->GetStellRadiusToPrimary(); if (StellationRadius == -1.0) { StellationRadius = Length; } else { if (Length != StellationRadius) MultipleStellationRadius = TRUE; } } // Test stellation offset angle ratio if (!MultipleStellationOffset) { double Offset = pShape->GetStellationRatio(); if (StellationOffset == -1000.0) { StellationOffset = Offset; PreviousNumSides = pShape->GetNumSides(); } else { if (((INT32)(Offset*1000) != (INT32)(StellationOffset*1000)) || (PreviousNumSides != pShape->GetNumSides())) MultipleStellationOffset = TRUE; } } // Test Primary Curvature if (!MultiplePrimaryCurvature) { if (PrimaryCurvature == -1.0) { PrimaryCurvature = pShape->GetPrimaryCurveToPrimary(); } else { if (PrimaryCurvature != pShape->GetPrimaryCurveToPrimary()) MultiplePrimaryCurvature = TRUE; } } // Test Stellation Curvature if (pShape->IsStellated() && pShape->IsStellationCurvature()) FoundStellatedCurve= TRUE; if (!MultipleStellationCurvature) { if (StellationCurvature == -1.0) { StellationCurvature = pShape->GetStellCurveToStell(); } else { if (StellationCurvature != pShape->GetStellCurveToStell()) MultipleStellationCurvature = TRUE; } } } } if (ShapeToShow == NULL) pNode = Selection->FindNext(pNode); else pNode = NULL; } String_32 Str; // Now update the edit fields BOOL EnableArray[6] = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE}; UINT32 loop; BOOL Blank = FALSE; BOOL MakeUpperMany = FALSE; BOOL MakeLowerMany = FALSE; BOOL FastUpdate = (ShapeToShow != NULL); if ((NoneSelected) || (Document::GetSelected() == NULL) || (Document::GetCurrent() == NULL)) Blank = TRUE; else { switch (pQuickShapeBase->EditFieldMode) { case QuickShapeBase::EDITF_CENTRE: if (MultipleCentres) { MakeLowerMany = MakeUpperMany = TRUE; } else { if(!SetEditPosition(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDC_EDIT_REGSHAPETOOL_LOWER), Centre, CurrentSpread, FastUpdate)) { Blank = TRUE; } } break; case QuickShapeBase::EDITF_MAJOR: if (MultipleMajorRadius) { MakeUpperMany = TRUE; } else { Blank = !SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), (INT32)MajorRadius, FastUpdate); } if (!Blank) { if (MultipleMajorAngle) { MakeLowerMany = TRUE; } else { // convert MajorAngle into the display value MajorAngle = MajorAngle*(180/PI) - 90; if (MajorAngle >= 0) MajorAngle -= 360; MajorAngle = -MajorAngle; if (MajorAngle >= 360.0) MajorAngle = 0.0; Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), MajorAngle); if (FastUpdate) PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER)); } } break; case QuickShapeBase::EDITF_STELLATION: if (MultipleStellationRadius) { MakeUpperMany = TRUE; } else { Blank = !SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), (INT32)StellationRadius, FastUpdate); } if (!Blank) { if (MultipleStellationOffset) { MakeLowerMany = TRUE; } else { ERROR3IF(PreviousNumSides == 0, "Trying to update stellation with no stellated sides!"); // convert StellationOffset into the display value if (PreviousNumSides != 0) { StellationOffset = StellationOffset*(360/PreviousNumSides); Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), StellationOffset); if (FastUpdate) PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER)); } } } break; case QuickShapeBase::EDITF_CURVE: if (MultiplePrimaryCurvature) { MakeUpperMany = TRUE; } else { Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), PrimaryCurvature); if (FastUpdate) PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_UPPER)); } if (!Blank) { if (MultipleStellationCurvature) { MakeLowerMany = TRUE; } else { Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), StellationCurvature); if (FastUpdate) PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER)); } } if (!FoundStellatedCurve) { EnableArray[1] = FALSE; EnableArray[4] = FALSE; EnableArray[5] = FALSE; } break; case QuickShapeBase::EDITF_SIZE: // Width in the upper field if (MultipleMinorRadius) MakeUpperMany = TRUE; else { if (pQuickShapeBase->IsRectangle()) MinorRadius = MinorRadius * cos (PI/4); Blank = !SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), (INT32)MinorRadius, FastUpdate); } // Height in the lower field if (MultipleMajorRadius || Blank) MakeLowerMany = TRUE; else { if (pQuickShapeBase->IsRectangle()) MajorRadius = MajorRadius * cos (PI/4); Blank = !SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), (INT32)MajorRadius, FastUpdate); } break; case QuickShapeBase::EDITF_ROT: if (MultipleMajorAngle) MakeUpperMany = TRUE; else { // convert MajorAngle into the display value MajorAngle = MajorAngle*(180/PI) - 90; if (MajorAngle >= 0) MajorAngle -= 360; MajorAngle = -MajorAngle; if (MajorAngle >= 360.0) MajorAngle = 0.0; Blank = !SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), MajorAngle); Str.Empty(); SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER),Str); if (FastUpdate) { PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_UPPER)); PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER)); } } EnableArray[1] = FALSE; EnableArray[4] = FALSE; EnableArray[5] = FALSE; break; default: ERROR3("Unknown edit field mode found when updating"); Blank = TRUE; break; } } if (MakeUpperMany) { Str.MakeMsg(_R(IDS_MANY)); SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER),Str); } if (MakeLowerMany) { Str.MakeMsg(_R(IDS_MANY)); SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER),Str); } if (Blank) { Str.Empty(); SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER),Str); SetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER),Str); for (loop = 0; loop < 6; EnableArray[loop++] = FALSE); } if (ShapeToShow == NULL) { EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_UPPER), EnableArray[0]); EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_LOWER), EnableArray[1]); EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_BUMPLEFT), EnableArray[2]); EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_BUMPRIGHT), EnableArray[3]); EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_BUMPUP), EnableArray[4]); EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_BUMPDOWN), EnableArray[5]); } SetHelp(); } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::IsEnabled(CGadgetID gid) Author: Phil_Martin (Xara Group Ltd) Created: 07/10/2005 Inputs: gid gadget identifier Outputs: - Returns: TRUE if the specified gadget is enabled FALSE if not, if it's "greyed out" Purpose: Test whether control is available to the user or not Errors: - SeeAlso: SelectorInfoBarOp::SetEdit Notes: Note that this function ignores ShapeToShow because the gadgets are only enabled or disable in the fucntion above when ShapeToShow is NULL ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::IsEnabled(CGadgetID gid) { SelRange* Selection = GetApplication()->FindSelection(); Node* pNode = Selection->FindFirst(); if( _R(IDC_EDIT_REGSHAPETOOL_BUMPLEFT) == gid || _R(IDC_EDIT_REGSHAPETOOL_BUMPRIGHT) == gid || _R(IDC_EDIT_REGSHAPETOOL_BUMPUP) == gid || _R(IDC_EDIT_REGSHAPETOOL_BUMPDOWN) ) { while (pNode != NULL) { if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode)) { NodeRegularShape* pShape = (NodeRegularShape*)pNode; CurrentSpread = pShape->FindParentSpread(); return TRUE; } pNode = Selection->FindNext(pNode); } } else ERROR3("IsEnabled behaviour not defined for this gadget\n"); return FALSE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::SetEdit(CGadgetID gid, INT32 nValue, BOOL PaintNow = FALSE) Author: Peter_Arnold (Xara Group Ltd) Created: 11/1/95 Inputs: gid gadget identifier nValue the value to set in the edit field (in millipoints PaintNow - TRUE if the edit filed should be redrawn immediatly. Outputs: - Returns: TRUE if everything suceeded, FALSE if an error occured Purpose: Converts the given value to the appropriate units, as contained in the spread, converts it to text and writes in into the edit-field. Errors: - SeeAlso: SelectorInfoBarOp::SetEdit ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::SetEdit(CGadgetID gid, INT32 nValue, BOOL PaintNow) { if (CurrentSpread != NULL) { // Get the dimension scaling object (units) associated with the given spread // and convert to its units. DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread); ERROR2IF (pDimScale == NULL, FALSE, "Null DimScale* in QuickShapeBaseInfoBarOp::SetEdit"); // Convert to units & text and display. String_256 str; pDimScale->ConvertToUnits((INT32) nValue, &str); if (!UpdateStringGadgetValue(gid, &str)) PaintNow = FALSE; } else { // No unit conversion possible, just convert to text. SetLongGadgetValue(gid, nValue); } if (PaintNow) PaintGadgetNow(gid); return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::SetEditPosition(CGadgetID gidX, CGadgetID gidY, DocCoord loc, Spread* pSpread, BOOL PaintNow) Author: Peter_Arnold (Xara Group Ltd) Created: 31/1/95 Inputs: gidX - gadget identifier for X field gidY - gadget identifier for Y field DocCoord - location to show pSpread - Spread containing the location PaintNow - TRUE if the edit fields should be redrawn immediatly. Outputs: - Returns: TRUE if everything suceeded, FALSE if an error occured Purpose: Converts the given coordinate to the appropriate units, as contained in the spread, converts it to text and writes in into the edit-field. Errors: - SeeAlso: SelectorInfoBarOp::SetEdit ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::SetEditPosition(CGadgetID gidX, CGadgetID gidY, DocCoord loc, Spread* pSpread, BOOL PaintNow) { ERROR2IF(pSpread == FALSE, FALSE, "Current spread was NULL"); String_256 XText; String_256 YText; pSpread->SpreadCoordToText(&XText, &YText, loc); BOOL UpdatedX = UpdateStringGadgetValue(gidX, &XText); BOOL UpdatedY = UpdateStringGadgetValue(gidY, &YText); if (PaintNow && UpdatedX) PaintGadgetNow(gidX); if (PaintNow && UpdatedY) PaintGadgetNow(gidY); return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::EditCommit(BOOL UpperCommit) Author: Peter_Arnold (Xara Group Ltd) Created: 17/1/95 Inputs: UpperCommit is TRUE if the upper edit field has been commited, FALSE for the lower edit field Outputs: - Returns: TRUE/FALSE for success/failure Purpose: Called when the user has committed a value in either of the edit fields Errors: - SeeAlso: - ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::EditCommit(BOOL UpperCommit) { ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer"); EditRegularShapeParam ChangeData(NULL); ChangeData.ShapesToAffect = (EditRegularShapeParam::AffectShape)pQuickShapeBase->GetShapesToAffect(); // Put changes into ChangeData depending on selected edit switch (pQuickShapeBase->EditFieldMode) { case QuickShapeBase::EDITF_CENTRE: if (!EditCommitCentre(UpperCommit, &ChangeData)) return FALSE; break; case QuickShapeBase::EDITF_MAJOR: if (!EditCommitSizeAndRotation(UpperCommit, &ChangeData)) return FALSE; break; case QuickShapeBase::EDITF_STELLATION: if (!EditCommitStellation(UpperCommit, &ChangeData)) return FALSE; break; case QuickShapeBase::EDITF_CURVE: if (!EditCommitCurvature(UpperCommit, &ChangeData)) return FALSE; break; case QuickShapeBase::EDITF_SIZE: if (!EditCommitWidthAndHeight(UpperCommit, &ChangeData)) return FALSE; break; case QuickShapeBase::EDITF_ROT: if (!EditCommitRotation(UpperCommit, &ChangeData)) return FALSE; break; default: ERROR3("Unknown edit field mode found when committing"); } // Invoke an operation to perform the changes OpDescriptor* Apple = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpEditRegularShape)); ERROR2IF(Apple == NULL, FALSE, "Couldn't find OpEditRegularShape's OpDescriptor"); Apple->Invoke(&ChangeData); return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::GetFieldCoord(DocCoord* pCoord,pSpread) Author: Peter_Arnold (Xara Group Ltd) Created: 17/1/95 Inputs: pCoord - pointer to a DocCoord to return the results in pSpread - the spread the object is on. Outputs: pCoord contains the coordinate shown in the edit field Returns: TRUE for success/ FALSE for validation error (pCoord is undefined) Purpose: Reads the text in the edit fields as coordinate values Errors: - SeeAlso: - ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::GetFieldCoord(DocCoord* pCoord, Spread* pSpread) { if (pSpread==NULL) return FALSE; BOOL Valid; String_64 strX; String_64 strY; String_16 ManyField; ManyField.Load(_R(IDS_MANY)); // Get the text strings from the edit fields strX = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid); if (strX == ManyField) Valid = FALSE; if (Valid) strY = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid); if (strY == ManyField) Valid = FALSE; if (Valid) Valid = pSpread->TextToSpreadCoord(pCoord, &strX, &strY); if (!Valid) Error::SetError(_R(IDE_INVALID_CENTRE)); return Valid; } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::SetToolMode() Author: Peter_Arnold (Xara Group Ltd) Created: 08/12/94 Inputs: - Outputs: - Returns: - Purpose: Sets the text in the infobars Add/Change field. Errors: - SeeAlso: - ********************************************************************************************/ void QuickShapeBaseInfoBarOp::SetToolMode() { if (pQuickShapeBase!=NULL) { String_16 Text; if (AreShapesSelected()) Text.Load(_R(IDS_BEZTOOL_CHANGE),Tool::GetModuleID(pQuickShapeBase->GetID())); else Text.Load(_R(IDS_BEZTOOL_NEW),Tool::GetModuleID(pQuickShapeBase->GetID())); SetStringGadgetValue(_R(IDC_REGSHAPETOOL_ADDCHANGE), Text); } } /******************************************************************************************** > INT32 QuickShapeBaseInfoBarOp::GetCreationMode() Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: - Outputs: - Returns: The creation mode that the info bar is in; either RADIUS, DIAMETER or BOUNDS Purpose: To read which of the creation modes is currently selected. Errors: ERROR3 if no buttons are selected (RADIUS is selected and returned) SeeAlso: QuickShapeBaseInfoBarOp::SetCreationMode ********************************************************************************************/ INT32 QuickShapeBaseInfoBarOp::GetCreationMode() { // Is the radius button selected? if (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_RADIUS), 0, 1)) { return (OpNewRegShape::RADIUS); } // Is the diameter button selected? if (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_DIAMETER), 0, 1)) { return (OpNewRegShape::DIAMETER); } // Is the bounds button selected? if (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_BOUNDBOX), 0, 1)) { return (OpNewRegShape::BOUNDS); } // To get here no button was selected - in debug builds do an ERROR3 // In retail builds select the radius button and return that ERROR3("No creation mode button was selected!"); SetCreationMode(OpNewRegShape::RADIUS); return (OpNewRegShape::RADIUS); } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::SetCreationMode(INT32 NewMode) Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: NewMode - the creation mode to put the infobar into. This should be either RADIUS, DIAMETER or BOUNDS Outputs: - Returns: - Purpose: To set the creation mode the infobar is in (ie it sets the three buttons). Errors: ERROR3 if NewMode is not one of the three recognised states. SeeAlso: QuickShapeBaseInfoBarOp::GetCreationMode ********************************************************************************************/ void QuickShapeBaseInfoBarOp::SetCreationMode(INT32 NewMode) { BOOL SelectRadius = FALSE; BOOL SelectDiameter = FALSE; BOOL SelectBounds = FALSE; // Now make one of the above TRUE depending on NewMode switch (NewMode) { case OpNewRegShape::RADIUS: SelectRadius = TRUE; break; case OpNewRegShape::DIAMETER: SelectDiameter = TRUE; break; case OpNewRegShape::BOUNDS: SelectBounds = TRUE; break; default: ERROR3("Invalid creation mode"); SelectRadius = TRUE; break; } // Now set the buttons if (WindowID != NULL) { SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_RADIUS), SelectRadius); SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_DIAMETER), SelectDiameter); SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_BOUNDBOX), SelectBounds); } } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::IsPolygonCreate() Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: - Outputs: - Returns: TRUE if the Create Polygons button is selected, FALSE if the Create Ellipses button is selected. Purpose: To read wether ploygons or ellipses should be created. Errors: - SeeAlso: QuickShapeBaseInfoBarOp::SetPolygonCreate() ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::IsPolygonCreate() { if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesPolygonExist()) return (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_POLYGON), 0, 1)) ; else return FALSE; } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::SetPolygonCreate(BOOL PolygonMode) Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: PolygonMode - TRUE if polygon mode should be selected, FALSE if ellipse mode shuld be selected. Outputs: - Returns: - Purpose: To set the selection state of the polygon/ellipse buttons. If ellipse mode then the curve and stellate buttons are greyed. Errors: - SeeAlso: QuickShapeBaseInfoBarOp::IsPolygonCreate ********************************************************************************************/ void QuickShapeBaseInfoBarOp::SetPolygonCreate(BOOL PolygonMode) { if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesReformSidesExist() && pQuickShapeBase->DoesNumSidesExist()) { SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_POLYGON), PolygonMode!=0); SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_ELLIPSE), PolygonMode==0); EnableGadget(_R(IDC_BTN_REGSHAPETOOL_POLYGON), !pQuickShapeBase->ForcePolygonToGrey()); EnableGadget(_R(IDC_BTN_REGSHAPETOOL_ELLIPSE), !pQuickShapeBase->ForceEllipseToGrey()); if (PolygonMode) { EnableGadget(_R(IDC_BTN_REGSHAPETOOL_STELLATION), !pQuickShapeBase->ForceStellationToGrey()); EnableGadget(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), !pQuickShapeBase->ForceCurvatureToGrey()); EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_SIDES), !pQuickShapeBase->ForceNumSidesToGrey()); } else { EnableGadget(_R(IDC_BTN_REGSHAPETOOL_STELLATION), FALSE); EnableGadget(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), FALSE); EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_SIDES), !pQuickShapeBase->ForceNumSidesToGrey()); } } } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::IsStellationCreate() Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: - Outputs: - Returns: TRUE if the stellation button is selected, FALSE if it isn't Purpose: To get the selection state of the stellation button. Errors: - SeeAlso: QuickShapeBaseInfoBarOp::SetStellationCreate ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::IsStellationCreate() { if (pQuickShapeBase!= NULL && pQuickShapeBase->DoesStellationExist()) return (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_STELLATION), 0, 1)) ; else return FALSE; } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::SetStellationCreate(BOOL StellationCreate) Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: StellationCreate - TRUE if the button should be selected, FALSE for deselection Outputs: - Returns: - Purpose: To set the selection state of the stellation button. Errors: - SeeAlso: BOOL QuickShapeBaseInfoBarOp::IsStellationCreate ********************************************************************************************/ void QuickShapeBaseInfoBarOp::SetStellationCreate(BOOL StellationCreate) { if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesStellationExist()) { if (pQuickShapeBase->ForceStellationToGrey()) StellationCreate = FALSE; SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_STELLATION), StellationCreate!=0); } } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::IsCurvedCreate() Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: - Outputs: - Returns: TRUE if the rounded edges button is selected, FALSE if it isn't Purpose: To get the selection state of the rounded edges button. Errors: - SeeAlso: QuickShapeBaseInfoBarOp::SetCurvedCreate ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::IsCurvedCreate() { if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesCurvatureExist()) return (GetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), 0, 1)) ; else return FALSE; } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::SetCurvedCreate(BOOL CurvedCreate) Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: CurvedCreate - TRUE if the button should be selected, FALSE for deselection Outputs: - Returns: - Purpose: To set the selection state of the rounded corners button. Errors: - SeeAlso: BOOL QuickShapeBaseInfoBarOp::IsCurvedCreate ********************************************************************************************/ void QuickShapeBaseInfoBarOp::SetCurvedCreate(BOOL CurvedCreate) { if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesCurvatureExist()) { if (pQuickShapeBase->ForceCurvatureToGrey()) CurvedCreate = FALSE; SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_CURVATURE), CurvedCreate!=0); } } /******************************************************************************************** > INT32 QuickShapeBaseInfoBarOp::GetNumSides(BOOL Error) Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: Error - TRUE means if the field is invalid then show an error to the user. Outputs: - Returns: The number of sides displaied in the infobar edit field. Purpose: To get the number of sides in the edit field. Errors: If the number in the edit field is invalid then the user is informed and -1 is returned (the edit field is forced to 3). Valid numbers of sides are between 3 and 99 inclusive. SeeAlso: QuickShapeBaseInfoBarOp::SetNumSides ********************************************************************************************/ INT32 QuickShapeBaseInfoBarOp::GetNumSides(BOOL Error) { if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesNumSidesExist()) { BOOL Valid; INT32 Result; if (Error) Result = GetLongGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES), 3, 99, _R(IDE_REGSHAPETOOL_SIDES), &Valid); else Result = GetLongGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES), 3, 99, 0, &Valid); if (Valid) return Result; else { SetNumSides(3); return -1; } } else return 3; } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::SetNumSides(INT32 NumberSides) Author: Peter_Arnold (Xara Group Ltd) Created: 22/11/94 Inputs: NumberSides - the number to display in the edit field Outputs: - Returns: - Purpose: To initialise the regular shape tool's infobar. In particular it sets up the number of sides listbox. A value of -1 means clear the field. Errors: ERROR3's if NumberSides is less than three or greater than the maximum SeeAlso: QuickShapeBaseInfoBarOp::GetNumSides ********************************************************************************************/ void QuickShapeBaseInfoBarOp::SetNumSides(INT32 NumberSides) { if (pQuickShapeBase!=NULL && pQuickShapeBase->DoesNumSidesExist()) { ERROR3IF(NumberSides > (INT32)REGULARSHAPE_MAXSIDES, "Tried to display more than the max number of sides"); // If the number is -1 then clear the field. if (NumberSides == -1) { SetSelectedValueIndex(_R(IDC_EDIT_REGSHAPETOOL_SIDES), -1); } else { SetLongGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_SIDES), NumberSides, FALSE, -1); // If the number is between 3 and 10 then select the menu item if ((NumberSides >= 3) && (NumberSides <= 10)) SetSelectedValueIndex(_R(IDC_EDIT_REGSHAPETOOL_SIDES), NumberSides-3); } } } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::SetBarFromSelection() Author: Peter_Arnold (Xara Group Ltd) Created: 25/11/94 Inputs: - Outputs: - Returns: TRUE if the bar was setup (FALSE if it wasn't (ie Add mode should be selected)) Purpose: Scans the selected items. If any Regular shapes are found then the infobar is setup using their parameters. Errors: - SeeAlso: QuickShapeBaseInfoBarOp::SetCreationMode, QuickShapeBaseInfoBarOp::SetPolygonCreate, QuickShapeBaseInfoBarOp::SetStellationCreate, QuickShapeBaseInfoBarOp::SetCurvedCreate, QuickShapeBaseInfoBarOp::SetNumSides ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::SetBarFromSelection() { ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer"); SelRange* Selection = GetApplication()->FindSelection(); Node* pNode = Selection->FindFirst(); BOOL FoundPolygon = FALSE; BOOL FoundEllipse = FALSE; BOOL FoundShape = FALSE; BOOL FoundStellated = FALSE; BOOL ShouldStellate = FALSE; BOOL FoundCurved = FALSE; BOOL ShouldCurve = FALSE; INT32 NumSides = 0; BOOL FoundMultipleSides = FALSE; BOOL FoundReformed = FALSE; while (pNode != NULL) { if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode)) { NodeRegularShape* pShape = (NodeRegularShape*)pNode; // If we haven't found a shape so far then set our var if (NumSides == 0) NumSides = pShape->GetNumSides(); else { if (!FoundMultipleSides && (NumSides != (INT32)pShape->GetNumSides())) { FoundMultipleSides = TRUE; NumSides = -1; } } // Now test for stellation if (!FoundStellated) { FoundStellated = TRUE; ShouldStellate = pShape->IsStellated(); } else { if (ShouldStellate != pShape->IsStellated()) ShouldStellate = FALSE; } // Now test for curvation if (!FoundCurved) { FoundCurved = TRUE; ShouldCurve = pShape->IsPrimaryCurvature(); } else { if (ShouldCurve != pShape->IsPrimaryCurvature()) ShouldCurve = FALSE; } // Now test for polygon/ellipse FoundShape = TRUE; FoundPolygon = FoundPolygon || !pShape->IsCircular(); FoundEllipse = FoundEllipse || pShape->IsCircular(); // Finally check the path edges FoundReformed = FoundReformed || pShape->IsReformed(); } pNode = Selection->FindNext(pNode); } if (pQuickShapeBase->DoesReformSidesExist()) EnableGadget(_R(IDC_BTN_REGSHAPETOOL_LINES), FoundReformed); if (FoundShape) { // If we have found polygons and ellipses then pop the buttons out // but allow editing of the number of sides if (FoundPolygon && FoundEllipse) { if (pQuickShapeBase->DoesPolygonExist()) SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_POLYGON), FALSE); if (pQuickShapeBase->DoesEllipseExist()) SetLongGadgetValue(_R(IDC_BTN_REGSHAPETOOL_ELLIPSE), FALSE); if (pQuickShapeBase->DoesNumSidesExist()) EnableGadget(_R(IDC_EDIT_REGSHAPETOOL_SIDES), TRUE); } else { SetPolygonCreate(FoundPolygon); } SetNumSides(NumSides); SetStellationCreate(ShouldStellate); SetCurvedCreate(ShouldCurve); pQuickShapeBase->SetNumSides(NumSides); pQuickShapeBase->SetPolygon(FoundPolygon); pQuickShapeBase->SetStellation(ShouldStellate); pQuickShapeBase->SetCurved(ShouldCurve); } else { SetNumSides(pQuickShapeBase->GetNumSides()); } return FoundShape; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::AreShapesSelected() Author: Peter_Arnold (Xara Group Ltd) Created: 08/12/94 Inputs: - Outputs: - Returns: TRUE if there are selected NodeRegularShapes in the document, FALSE if there arn't Purpose: To see if there are any regular shapes in the current selection. Also sets the member variable ChangeMode to the return value. Errors: - SeeAlso: - ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::AreShapesSelected() { ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer"); SelRange* Selection = GetApplication()->FindSelection(); Node* pNode = Selection->FindFirst(); while (pNode != NULL) { if (IS_A(pNode, NodeRegularShape) && pQuickShapeBase->IsInterestingShape((NodeRegularShape*)pNode)) { ChangeMode = TRUE; return TRUE; } pNode = Selection->FindNext(pNode); } ChangeMode = FALSE; return FALSE; } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::UpdateInfobar() Author: Peter_Arnold (Xara Group Ltd) Created: 08/12/94 Inputs: - Outputs: - Returns: - Purpose: To ensure the infobar is up-to-date. Called on initial creation and selection changes. Errors: - SeeAlso: - ********************************************************************************************/ void QuickShapeBaseInfoBarOp::UpdateInfobar() { if (WindowID!=NULL && pQuickShapeBase!=NULL) { SetToolMode(); if (!SetBarFromSelection()) { SetPolygonCreate(pQuickShapeBase->GetPolygon()); SetStellationCreate(pQuickShapeBase->GetStellation()); SetCurvedCreate(pQuickShapeBase->GetCurved()); SetNumSides(pQuickShapeBase->GetNumSides()); } } } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::BumpLeft() Author: Peter_Arnold (Xara Group Ltd) Created: 17/1/95 Inputs: - Outputs: - Returns: TRUE/FALSE for success/failure Purpose: Called when the user clicks on the bump left button. Does different things depeding on what the edit fields are displaying Errors: - SeeAlso: QuickShapeBaseInfoBarOp::BumpRight, QuickShapeBaseInfoBarOp::BumpUp, QuickShapeBaseInfoBarOp::BumpDown ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::BumpLeft() { ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer"); // Get the current edit field BOOL Valid = TRUE; ERROR2IF(CurrentSpread == NULL, FALSE, "BumpLeft found CurrentSpread was NULL"); DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread); ERROR2IF(pDimScale == NULL, FALSE, "NULL DimScalePtr"); String_256 FieldContents = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid); // Bump it if (Valid) { switch (pQuickShapeBase->EditFieldMode) { // bump centre left, bump down major length, bump down size, bump down stellation case QuickShapeBase::EDITF_CENTRE: case QuickShapeBase::EDITF_MAJOR: case QuickShapeBase::EDITF_SIZE: case QuickShapeBase::EDITF_STELLATION: { MILLIPOINT CurrentPos = 0; Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos); if (Valid) { CurrentPos -= OpNudge::GetNudgeStep(); if ((pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_MAJOR) || (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_SIZE)) { if (CurrentPos>100) CurrentPos=100; } if (pQuickShapeBase->EditFieldMode == QuickShapeBase::EDITF_STELLATION) { if (CurrentPos>0) CurrentPos=0; } SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentPos, TRUE); } } break; case QuickShapeBase::EDITF_CURVE: { double CurrentCurve = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), 0, 100, 0, &Valid); if (Valid) { CurrentCurve -= .05; if (CurrentCurve < 0) CurrentCurve = 0; SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentCurve); } } break; // Rotate anti-clockwise by 5 degrees case QuickShapeBase::EDITF_ROT: { double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), -360, 360, 0, &Valid); if (Valid) { CurrentRot = RestrictAngleZero360(CurrentRot - 5); SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentRot); } } break; default: ERROR2(FALSE, "Unknown edit field mode found when bumping left"); } PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_UPPER)); } return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::BumpRight() Author: Peter_Arnold (Xara Group Ltd) Created: 17/1/95 Inputs: - Outputs: - Returns: TRUE/FALSE for success/failure Purpose: Called when the user clicks on the bump right button. Does different things depeding on what the edit fields are displaying Errors: - SeeAlso: QuickShapeBaseInfoBarOp::BumpLeft, QuickShapeBaseInfoBarOp::BumpUp, QuickShapeBaseInfoBarOp::BumpDown ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::BumpRight() { ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer"); // Get the current edit field BOOL Valid = TRUE; ERROR2IF(CurrentSpread == NULL, FALSE, "BumpRight found CurrentSpread was NULL"); DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread); ERROR2IF(pDimScale == NULL, FALSE, "NULL DimScalePtr"); String_256 FieldContents = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid); // Bump it if (Valid) { switch (pQuickShapeBase->EditFieldMode) { // bump centre right, bump up major length, bump up size, bump up stellation case QuickShapeBase::EDITF_CENTRE: case QuickShapeBase::EDITF_MAJOR: case QuickShapeBase::EDITF_SIZE: case QuickShapeBase::EDITF_STELLATION: { MILLIPOINT CurrentPos = 0; Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos); if (Valid) { CurrentPos += OpNudge::GetNudgeStep(); SetEdit(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentPos, TRUE); } } break; case QuickShapeBase::EDITF_CURVE: { double CurrentCurve = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), 0, 100, 0, &Valid); if (Valid) { CurrentCurve += .05; SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentCurve); } } break; // Rotate clockwise by 5 degrees case QuickShapeBase::EDITF_ROT: { double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), -360, 360, 0, &Valid); if (Valid) { CurrentRot = RestrictAngleZero360(CurrentRot + 5); SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), CurrentRot); } } break; default: ERROR2(FALSE, "Unknown edit field mode found when bumping right"); } PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_UPPER)); } return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::BumpUp() Author: Peter_Arnold (Xara Group Ltd) Created: 17/1/95 Inputs: - Outputs: - Returns: TRUE/FALSE for success/failure Purpose: Called when the user clicks on the bump up button. Does different things depeding on what the edit fields are displaying Errors: - SeeAlso: QuickShapeBaseInfoBarOp::BumpLeft, QuickShapeBaseInfoBarOp::BumpRight, QuickShapeBaseInfoBarOp::BumpDown ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::BumpUp() { ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer"); // Get the current edit field BOOL Valid = TRUE; ERROR2IF(CurrentSpread == NULL, FALSE, "BumpRight found CurrentSpread was NULL"); DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread); ERROR2IF(pDimScale == NULL, FALSE, "NULL DimScalePtr"); String_256 FieldContents = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid); // Bump it if (Valid) { switch (pQuickShapeBase->EditFieldMode) { // bump centre up case QuickShapeBase::EDITF_CENTRE: { MILLIPOINT CurrentPos = 0; Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos); if (Valid) { CurrentPos -= OpNudge::GetNudgeStep(); SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentPos, TRUE); } } break; case QuickShapeBase::EDITF_SIZE: { MILLIPOINT CurrentPos = 0; Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos); if (Valid) { CurrentPos -= OpNudge::GetNudgeStep(); if (CurrentPos < 0) CurrentPos = 0; SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentPos, TRUE); } } break; // Rotate anti-clockwise by 5 degrees case QuickShapeBase::EDITF_MAJOR: { double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -360, 360, 0, &Valid); if (Valid) { CurrentRot = RestrictAngleZero360(CurrentRot - 5); SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentRot); } } break; // Rotate stellation offset anti-clockwise by 5 degrees case QuickShapeBase::EDITF_STELLATION: { double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -180, 180, 0, &Valid); if (Valid) { CurrentRot = RestrictAngleMinus180(CurrentRot - 5); SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentRot); } } break; case QuickShapeBase::EDITF_CURVE: { double CurrentCurve = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), 0, 100, 0, &Valid); if (Valid) { CurrentCurve -= .05; if (CurrentCurve < 0) CurrentCurve = 0; SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentCurve); } } break; default: ERROR2(FALSE, "Unknown edit field mode found when bumping up"); } } PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER)); return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::BumpDown() Author: Peter_Arnold (Xara Group Ltd) Created: 17/1/95 Inputs: - Outputs: - Returns: TRUE/FALSE for success/failure Purpose: Called when the user clicks on the bump down button. Does different things depeding on what the edit fields are displaying Errors: - SeeAlso: QuickShapeBaseInfoBarOp::BumpLeft, QuickShapeBaseInfoBarOp::BumpRight, QuickShapeBaseInfoBarOp::BumpUp ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::BumpDown() { ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer"); // Get the current edit field BOOL Valid = TRUE; ERROR2IF(CurrentSpread == NULL, FALSE, "BumpRight found CurrentSpread was NULL"); DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread); ERROR2IF(pDimScale == NULL, FALSE, "NULL DimScalePtr"); String_256 FieldContents = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid); // Bump it if (Valid) { switch (pQuickShapeBase->EditFieldMode) { // bump centre down, and size down case QuickShapeBase::EDITF_CENTRE: { MILLIPOINT CurrentPos = 0; Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos); if (Valid) { CurrentPos += OpNudge::GetNudgeStep(); SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentPos, TRUE); } } break; case QuickShapeBase::EDITF_SIZE: { MILLIPOINT CurrentPos = 0; Valid = pDimScale->ConvertToMillipoints(FieldContents, &CurrentPos); if (Valid) { CurrentPos += OpNudge::GetNudgeStep(); SetEdit(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentPos, TRUE); } } break; // Rotate clockwise by 5 degrees case QuickShapeBase::EDITF_MAJOR: { double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -360, 360, 0, &Valid); if (Valid) { CurrentRot = RestrictAngleZero360(CurrentRot + 5); SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentRot); } } break; // Rotate stellation offset clockwise by 5 degrees case QuickShapeBase::EDITF_STELLATION: { double CurrentRot = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -180, 180, 0, &Valid); if (Valid) { CurrentRot = RestrictAngleMinus180(CurrentRot + 5); SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentRot); } } break; case QuickShapeBase::EDITF_CURVE: { double CurrentCurve = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), 0, 100, 0, &Valid); if (Valid) { CurrentCurve += .05; if (CurrentCurve < 0) CurrentCurve = 0; SetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), CurrentCurve); } } break; default: ERROR2(FALSE, "Unknown edit field mode found when bumping down"); } } PaintGadgetNow(_R(IDC_EDIT_REGSHAPETOOL_LOWER)); return TRUE; } /******************************************************************************************** > double QuickShapeBaseInfoBarOp::RestrictAngleZero360(double Current) Author: Peter_Arnold (Xara Group Ltd) Created: 32/8/95 Inputs: Current - an angle Outputs: - Returns: Current restricted between 0 and 360. eg 372 becomes 12 Purpose: Restricts an angle for display purposes Errors: - SeeAlso: QuickShapeBaseInfoBarOp::RestrictAngleMinus180 ********************************************************************************************/ double QuickShapeBaseInfoBarOp::RestrictAngleZero360(double Current) { while (Current >= 360.0) Current -= 360; while (Current < 0) Current += 360; return Current; } /******************************************************************************************** > double QuickShapeBaseInfoBarOp::RestrictAngleMinus180(double Current) Author: Peter_Arnold (Xara Group Ltd) Created: 32/8/95 Inputs: Current - an angle Outputs: - Returns: Current restricted between -180 and 180. eg 192 becomes -168 Purpose: Restricts an angle for display purposes Errors: - SeeAlso: QuickShapeBaseInfoBarOp::RestrictAngleZero360 ********************************************************************************************/ double QuickShapeBaseInfoBarOp::RestrictAngleMinus180(double Current) { while (Current <= -180.0) Current += 360; while (Current > 180.0) Current -= 360; return Current; } /******************************************************************************************** > void QuickShapeBaseInfoBarOp::SetHelp() Author: Peter_Arnold (Xara Group Ltd) Created: 1/5/95 Inputs: - Outputs: - Returns: - Purpose: Sets the bubble and status line help on the edit fields depending on the current menu setting. Errors: - SeeAlso: - ********************************************************************************************/ void QuickShapeBaseInfoBarOp::SetHelp() { if (pQuickShapeBase!=NULL) { switch (pQuickShapeBase->EditFieldMode) { case QuickShapeBase::EDITF_CENTRE: SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_CENTREX), _R(IDS_REGSHAPETOOL_CENTREX)); SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPETOOL_CENTREY), _R(IDS_REGSHAPETOOL_CENTREY)); break; case QuickShapeBase::EDITF_MAJOR: SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_SIZE), _R(IDS_REGSHAPETOOL_SIZE)); SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPETOOL_ROTATION), _R(IDS_REGSHAPETOOL_ROTATION)); break; case QuickShapeBase::EDITF_STELLATION: SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_STELLSIZE), _R(IDS_REGSHAPETOOL_STELLSIZE)); SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPETOOL_STELLOFF), _R(IDS_REGSHAPETOOL_STELLOFF)); break; case QuickShapeBase::EDITF_CURVE: SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_PRIMER), _R(IDS_REGSHAPETOOL_PRIMER)); SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPETOOL_STELLR), _R(IDS_REGSHAPETOOL_STELLR)); break; case QuickShapeBase::EDITF_SIZE: SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPE_WIDTH), _R(IDS_REGSHAPE_WIDTH)); SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), _R(IDBBL_REGSHAPE_HEIGHT), _R(IDS_REGSHAPE_HEIGHT)); break; case QuickShapeBase::EDITF_ROT: SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_UPPER), _R(IDBBL_REGSHAPETOOL_ROTATION), _R(IDS_REGSHAPETOOL_ROTATION)); SetGadgetHelp(_R(IDC_EDIT_REGSHAPETOOL_LOWER), 0, 0); break; default: ERROR3("Unknown edit field mode found when setting help"); } } } /********************************************************************************************* Preference: CreationMode Section: RegularShapeTool Range: 0, 1 or 2 Purpose: The way shapes are created by dragging. SeeAlso: - **********************************************************************************************/ /********************************************************************************************* Preference: NumSides Section: RegularShapeTool Range: 3 to 99 inclusive Purpose: The number of sides to create shapes with SeeAlso: - **********************************************************************************************/ /********************************************************************************************* Preference: CreatePolygons Section: RegularShapeTool Range: TRUE or FALSE Purpose: Whether to create polygons (TRUE) or ellipses (FALSE) SeeAlso: - **********************************************************************************************/ /********************************************************************************************* Preference: CreateStellated Section: RegularShapeTool Range: TRUE or FALSE Purpose: Whether to create stellated shapes or not SeeAlso: - **********************************************************************************************/ /********************************************************************************************* Preference: CreateCurved Section: RegularShapeTool Range: TRUE or FALSE Purpose: Whether to create shapes with rounded corners SeeAlso: - **********************************************************************************************/ /******************************************************************************************** > QuickShapeTool::QuickShapeTool() Author: Peter_Arnold (Xara Group Ltd) Created: 18/03/95 Inputs: - Outputs: - Returns: - Purpose: Constructor for the QuickShape tool Errors: - SeeAlso: - ********************************************************************************************/ QuickShapeTool::QuickShapeTool() : QuickShapeBase() { } /******************************************************************************************** > QuickShapeTool::~QuickShapeTool() Author: Peter_Arnold (Xara Group Ltd) Created: 18/03/95 Inputs: - Outputs: - Returns: - Purpose: QuickShapes tools destructor Errors: - SeeAlso: - ********************************************************************************************/ QuickShapeTool::~QuickShapeTool() { } /******************************************************************************************** > BOOL QuickShapeTool::Init() Author: Peter_Arnold (Xara Group Ltd) Created: 18/03/95 Inputs: - Outputs: - Returns: TRUE/FALSE for success/failure Purpose: Called to initialise the QuickShape tool. Also initialases the base class Errors: - SeeAlso: QuickShapeBase::Init ********************************************************************************************/ BOOL QuickShapeTool::Init() { // Rread in the preference settings from the file GetApplication()->DeclareSection(_T("RegularShapeTool"),5); GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("CreationType"), &CreationMode, OpNewRegShape::RADIUS, OpNewRegShape::BOUNDS); GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("NumberSides"), &NumSides, 3, 99); GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("CreatePolygons"), &CreatePolygons, 0, 1); GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("CreateStellated"), &CreateStellated, 0, 1); GetApplication()->DeclarePref(_T("RegularShapeTool"),_T("CreateCurved"), &CreateCurved, 0, 1); // Initialise the base class first return QuickShapeBase::Init(); } /******************************************************************************************** > void QuickShapeTool::Describe(void *InfoPtr) Author: Peter_Arnold (Xara Group Ltd) Created: 15/11/94 Inputs: InfoPtr - A pointer to a tool info block. Outputs: InfoPtr - The structure pointed to by InfoPtr will have had all the info that this version of the Tool knows about Purpose: Allows the tool manager to extract information about the tool ********************************************************************************************/ void QuickShapeTool::Describe(void *InfoPtr) { // Cast structure into the latest one we understand. ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr; Info->InfoVersion = 1; Info->InterfaceVersion = GetToolInterfaceVersion(); Info->Version = 1; Info->ID = GetID(); Info->TextID = _R(IDS_REGSHAPE_TOOL); Info->Family = FamilyName; Info->Name = ToolName; Info->Purpose = Purpose; Info->Author = Author; Info->BubbleID = _R(IDBBL_REGSHAPE_TOOLBOX); } void QuickShapeTool::SetNumSides(INT32 NewValue) { if (!pQuickShapeBaseInfoBarOp->AreShapesSelected()) NumSides = NewValue; } void QuickShapeTool::SetCreationMode(INT32 NewValue) { CreationMode = NewValue; } void QuickShapeTool::SetPolygon(BOOL NewValue) { if (!pQuickShapeBaseInfoBarOp->AreShapesSelected()) CreatePolygons = NewValue; } void QuickShapeTool::SetStellation(BOOL NewValue) { if (!pQuickShapeBaseInfoBarOp->AreShapesSelected()) CreateStellated = NewValue; } void QuickShapeTool::SetCurved(BOOL NewValue) { if (!pQuickShapeBaseInfoBarOp->AreShapesSelected()) CreateCurved = NewValue; } /******************************************************************************************** > virtual BOOL QuickShapeTool::IsInterestingShape(NodeRegularShape* pShape) Author: Peter_Arnold (Xara Group Ltd) Created: 19/03/95 Inputs: pShape - points to a regular shape in the document Outputs: - Returns: TRUE if the shape is one processed by this tool Purpose: Always returns TRUE as the QuickShape tool deals with all shapes ********************************************************************************************/ BOOL QuickShapeTool::IsInterestingShape(NodeRegularShape* pShape) { return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::EditCommitCentre(BOOL UpperCommit, EditRegularShapeParam* ChangeData) Author: Peter_Arnold (Xara Group Ltd) Created: 8/1/96 Inputs: UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one ChangeData - the changes data Outputs: Changes to be made are output into ChangesData Returns: TRUE if all ok, FALSE if an error occured Purpose: Does the processing involved when the user changes a vales in the edit fields when in centre mode. ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::EditCommitCentre(BOOL UpperCommit, EditRegularShapeParam* ChangeData) { // The edit fields define a coordinate to move the centre points of all selected shapes to DocCoord NewCentre; if (!GetFieldCoord(&NewCentre, CurrentSpread) ) { Error::SetError(_R(IDE_REGSHAPE_CENTREOFFSPREAD)); return FALSE; } // Check the centre is on the spread BOOL OnSpread = TRUE; if (CurrentSpread != NULL) { DocRect SpreadBounds = CurrentSpread->GetPasteboardRect(FALSE); SpreadBounds = SpreadBounds.ToSpread(CurrentSpread, DocView::GetSelected()); OnSpread = SpreadBounds.ContainsCoord(NewCentre); } if (OnSpread) { ChangeData->TranslateTo = NewCentre; return TRUE; } else { Error::SetError(_R(IDE_REGSHAPE_CENTREOFFSPREAD)); return FALSE; } } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::EditCommitSizeAndRotation(BOOL UpperCommit, EditRegularShapeParam* ChangeData) Author: Peter_Arnold (Xara Group Ltd) Created: 8/1/96 Inputs: UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one ChangeData - the changes data Outputs: Changes to be made are output into ChangesData Returns: TRUE if all ok, FALSE if an error occured Purpose: Does the processing involved when the user changes a vales in the edit fields when in size and rotation mode. ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::EditCommitSizeAndRotation(BOOL UpperCommit, EditRegularShapeParam* ChangeData) { // Get the length string from the upper edit field, checking that it is not the "many" string String_32 EditFieldString; String_16 ManyField(_R(IDS_MANY)); BOOL Many = FALSE; BOOL Valid = TRUE; EditFieldString = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid); if (ManyField == EditFieldString) Many = TRUE; // Convert the length string to millipoints DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread); ERROR2IF (pDimScale == NULL, FALSE, "Null DimScale* in QuickShapeBaseInfoBarOp::GetFieldCoord"); INT32 Length = 0; if (Valid && !Many) Valid = pDimScale->ConvertToMillipoints(EditFieldString, &Length); if (!Valid && UpperCommit) { Error::SetError(_R(IDE_INVALID_RADIUS)); return FALSE; } else { if (Valid && !Many) { // Check the new length is less than the diagonal of the spread INT32 Diagonal = 0; if (CurrentSpread != NULL) { DocRect SpreadBounds = CurrentSpread->GetPasteboardRect(FALSE); SpreadBounds = SpreadBounds.ToSpread(CurrentSpread, DocView::GetSelected()); Diagonal = (INT32)sqrt((double)SpreadBounds.Width()*(double)SpreadBounds.Width() + (double)SpreadBounds.Height()*(double)SpreadBounds.Height()); } if (Length/2 == 0) { Error::SetError(_R(IDS_REGSHAPETOOL_TOOSMALL)); return FALSE; } else if ((CurrentSpread != NULL) && (Length > Diagonal)) { Error::SetError(_R(IDS_REGSHAPETOOL_TOOLARGE)); return FALSE; } else ChangeData->SetRadiusLength = Length/2; } } // Get the rotation value from the upper edit field, checking that it is not the "many" string Many = (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid)); double Angle = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -360.0, 360.0, 0, &Valid); if (!Valid && !UpperCommit) { Error::SetError(_R(IDE_INVALID_ANGLE)); return FALSE; } else { // convert Angle back from the display value if (Valid && !Many) { Angle = -Angle; if (Angle > 0) Angle -= 360; ChangeData->RotateTo = Angle*(PI/180) + (PI/2); } } return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::EditCommitStellation(BOOL UpperCommit, EditRegularShapeParam* ChangeData) Author: Peter_Arnold (Xara Group Ltd) Created: 8/1/96 Inputs: UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one ChangeData - the changes data Outputs: Changes to be made are output into ChangesData Returns: TRUE if all ok, FALSE if an error occured Purpose: Does the processing involved when the user changes a vales in the edit fields when in stellation mode. ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::EditCommitStellation(BOOL UpperCommit, EditRegularShapeParam* ChangeData) { // The upper field is the length to make the stellation radi of all selected shapes String_32 EditFieldString; String_16 ManyField(_R(IDS_MANY)); BOOL Many = FALSE; BOOL Valid = TRUE; EditFieldString = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid); if (ManyField == EditFieldString) Many = TRUE; // Convert string in to millipoints DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread); ERROR2IF (pDimScale == NULL, FALSE, "Null DimScale*"); INT32 Length = 0; if (Valid) Valid = pDimScale->ConvertToMillipoints(EditFieldString, &Length); if (!Valid && UpperCommit) { Error::SetError(_R(IDE_INVALID_RADIUS)); return FALSE; } else { if (Valid && !Many) ChangeData->SetStellationLength = Length; } // The lower field is the rotation angle to set on all the shapes Many = (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid)); double Angle = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), -180.0, 180.0, 0, &Valid); if (!Valid && !UpperCommit) { Error::SetError(_R(IDE_INVALID_STELLATIONOFFSET)); return FALSE; } else { // convert Angle back from the display value if (Valid && !Many) ChangeData->SetStellationOffset = float(Angle); } return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::EditCommitCurvature(BOOL UpperCommit, EditRegularShapeParam* ChangeData) Author: Peter_Arnold (Xara Group Ltd) Created: 8/1/96 Inputs: UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one ChangeData - the changes data Outputs: Changes to be made are output into ChangesData Returns: TRUE if all ok, FALSE if an error occured Purpose: Does the processing involved when the user changes a vales in the edit fields when in curvature mode. ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::EditCommitCurvature(BOOL UpperCommit, EditRegularShapeParam* ChangeData) { // The upper field is the primary curvature ratio String_16 ManyField(_R(IDS_MANY)); BOOL Valid = TRUE; BOOL Many = FALSE; if (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid)) Many = TRUE; double NewRatio = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), 0.0, 100.0, 0, &Valid); if (!Valid && UpperCommit) { Error::SetError(_R(IDE_INVALID_CURVATURE)); return FALSE; } else { if (Valid && !Many) ChangeData->NewPrimaryCurveToPrimary = float(NewRatio); } // The lower field is the stellation curvature ratio Many = (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid)); NewRatio = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), 0.0, 100.0, 0, &Valid); if (!Valid && !UpperCommit) { Error::SetError(_R(IDE_INVALID_CURVATURE)); return FALSE; } else { if (Valid && !Many) ChangeData->NewStellCurveToStell = float(NewRatio); } return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::EditCommitWidthAndHeight(BOOL UpperCommit, EditRegularShapeParam* ChangeData) Author: Peter_Arnold (Xara Group Ltd) Created: 8/1/96 Inputs: UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one ChangeData - the changes data Outputs: Changes to be made are output into ChangesData Returns: TRUE if all ok, FALSE if an error occured Purpose: Does the processing involved when the user changes a vales in the edit fields when in width and height mode. ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::EditCommitWidthAndHeight(BOOL UpperCommit, EditRegularShapeParam* ChangeData) { ERROR2IF(pQuickShapeBase==NULL, FALSE, "NULL tool pointer"); // The upper field is the length to make the minor axis of all selected shapes String_32 EditFieldString; String_16 ManyField(_R(IDS_MANY)); BOOL Many = FALSE; BOOL Valid = TRUE; EditFieldString = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid); if (ManyField == EditFieldString) Many = TRUE; // Convert string to millipoints DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) CurrentSpread); ERROR2IF (pDimScale == NULL, FALSE, "Null DimScale* in QuickShapeBaseInfoBarOp::GetFieldCoord"); INT32 Length = 0; if (Valid && !Many) Valid = pDimScale->ConvertToMillipoints(EditFieldString, &Length); if (!Valid && UpperCommit) { Error::SetError(_R(IDE_INVALID_RADIUS)); return FALSE; } else { if (Valid && !Many) { if (pQuickShapeBase->IsRectangle()) Length = (INT32)(Length / cos (PI/4)); // Check the new length is less than the diagonal of the spread INT32 Diagonal = 0; if (CurrentSpread != NULL) { DocRect SpreadBounds = CurrentSpread->GetPasteboardRect(FALSE); SpreadBounds = SpreadBounds.ToSpread(CurrentSpread, DocView::GetSelected()); Diagonal = (INT32)sqrt((double)SpreadBounds.Width()*(double)SpreadBounds.Width() + (double)SpreadBounds.Height()*(double)SpreadBounds.Height()); } if (Length/2 == 0) { Error::SetError(_R(IDS_REGSHAPETOOL_TOOSMALL)); return FALSE; } else if (Length > Diagonal) { Error::SetError(_R(IDS_REGSHAPETOOL_TOOLARGE)); return FALSE; } else ChangeData->SetMinorAxisLength = Length/2; } } // The lower field is the length to make the major axis of all selected shapes EditFieldString = GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_LOWER), &Valid); if (ManyField == EditFieldString) Many = TRUE; if (Valid && !Many) Valid = pDimScale->ConvertToMillipoints(EditFieldString, &Length); if (!Valid && !UpperCommit) { Error::SetError(_R(IDE_INVALID_RADIUS)); return FALSE; } else { if (Valid && !Many) { if (pQuickShapeBase->IsRectangle()) Length = (INT32)(Length / cos (PI/4)); // Check the new length is less than the diagonal of the spread INT32 Diagonal = 0; if (CurrentSpread != NULL) { DocRect SpreadBounds = CurrentSpread->GetPasteboardRect(FALSE); SpreadBounds = SpreadBounds.ToSpread(CurrentSpread, DocView::GetSelected()); Diagonal = (INT32)sqrt((double)SpreadBounds.Width()*(double)SpreadBounds.Width() + (double)SpreadBounds.Height()*(double)SpreadBounds.Height()); } if (Length/2 == 0) { Error::SetError(_R(IDS_REGSHAPETOOL_TOOSMALL)); return FALSE; } else if (Length > Diagonal) { Error::SetError(_R(IDS_REGSHAPETOOL_TOOLARGE)); return FALSE; } else ChangeData->SetMajorAxisLength = Length/2; } } return TRUE; } /******************************************************************************************** > BOOL QuickShapeBaseInfoBarOp::EditCommitRotation(BOOL UpperCommit, EditRegularShapeParam* ChangeData) Author: Peter_Arnold (Xara Group Ltd) Created: 8/1/96 Inputs: UpperCommit - TRUE if the upper edit field was commited; FALSE for the lower one ChangeData - the changes data Outputs: Changes to be made are output into ChangesData Returns: TRUE if all ok, FALSE if an error occured Purpose: Does the processing involved when the user changes a vales in the edit fields when in rotation mode. ********************************************************************************************/ BOOL QuickShapeBaseInfoBarOp::EditCommitRotation(BOOL UpperCommit, EditRegularShapeParam* ChangeData) { // The lower field is the rotation angle to set on all the shapes String_16 ManyField(_R(IDS_MANY)); BOOL Valid = TRUE; BOOL Many = (ManyField == GetStringGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), &Valid)); double Angle = GetDoubleGadgetValue(_R(IDC_EDIT_REGSHAPETOOL_UPPER), -360.0, 360.0, 0, &Valid); if (!Valid && UpperCommit) { Error::SetError(_R(IDE_INVALID_ANGLE)); return FALSE; } else { // convert Angle back from the display value if (Valid && !Many) { Angle = -Angle; if (Angle > 0) Angle -= 360; ChangeData->RotateTo = Angle*(PI/180) + (PI/2); } } return TRUE; }