00001 // $Id: selinfo.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // Selector Tool info-bar operations 00099 00100 /* 00101 */ 00102 00103 #include "camtypes.h" 00104 //#include "dlgtypes.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 #include "selector.h" 00106 #include "selinfo.h" 00107 //#include "selmsg.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00110 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 #include "opnudge.h" 00113 //#include "justin.h" 00114 //#include "fillattr.h" // For CC_RUNTIME_CLASS(AttrFillChanged) - in camtypes.h [AUTOMATICALLY REMOVED] 00115 #include "optsmsgs.h" 00116 #include "userrect.h" 00117 //#include "barsdlgs.h" 00118 00119 00120 //Matt 11/11/00 - I only wanted a function from the next line... 00121 #include "slicehelper.h" //For helper functions 00122 00123 //But I had to include all of these to get it to work!!... 00124 //#include "cxfrech.h" //For CamelotRecordHandler - in camtypes.h [AUTOMATICALLY REMOVED] 00125 #include "userattr.h" //For UserAttr 00126 #include "tmpltatr.h" //For TemplateAttribute 00127 00128 00129 DECLARE_SOURCE( "$Revision: 1282 $" ); 00130 CC_IMPLEMENT_DYNCREATE(SelectorInfoBarOp, InformationBarOp) 00131 00132 #define new CAM_DEBUG_NEW 00133 00134 00135 // This defines a pointer to a SelectorTool member function that takes two INT32s and 00136 // returns nothing. It is used to present a uniform interface to the DoXXXXImmediate 00137 // functions, which respond to changes in the info-bar edit-fields. 00138 typedef void (SelectorTool::*SELTOOLFUNC)(INT32, INT32); 00139 00140 00141 // These maintain the state of the info-bar's buttons. 00142 BOOL SelectorInfoBarOp::fLockAspect = TRUE; 00143 BOOL SelectorInfoBarOp::fRotateMode = FALSE; 00144 BOOL SelectorInfoBarOp::fScaleLines = TRUE; 00145 // BOOL SelectorInfoBarOp::fLeaveCopy = FALSE; 00146 // BOOL SelectorInfoBarOp::fTransFills = TRUE; 00147 00148 00149 00150 /******************************************************************************************** 00151 > SelectorInfoBarOp::SelectorInfoBarOp() 00152 00153 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00154 Created: 11/7/94 00155 Purpose: Default constructor for a SelectorInfoBarOp. 00156 SeeAlso: class InformationBarOp 00157 ********************************************************************************************/ 00158 00159 SelectorInfoBarOp::SelectorInfoBarOp() 00160 : pSelectorTool(NULL) 00161 { 00162 DlgResID = _R(IDD_SELECTORINFO); 00163 } 00164 00165 00166 00167 /******************************************************************************************** 00168 > virtual MsgResult SelectorInfoBarOp::Message(Msg* pMessage) 00169 00170 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00171 Created: 11/7/94 00172 Inputs: pMessage - A pointer to a dialog message. 00173 Returns: The result of the message. 00174 Purpose: Takes a look at the message and if it is for for selector tool info-bar 00175 then respond to it. 00176 Errors: - 00177 SeeAlso: SelectorInfoBarOp::HandleCreate; SelectorInfoBarOp::HandleButtonDown; 00178 SelectorInfoBarOp::HandleSelChange; SelectorTool::SelectionHasChanged 00179 ********************************************************************************************/ 00180 00181 MsgResult SelectorInfoBarOp::Message(Msg* pMessage) 00182 { 00183 // If we aren't the current tool then pass to the base class. 00184 if (((SelectorTool*) Tool::GetCurrent()) != pSelectorTool /* || !HasWindow() */) 00185 { 00186 return InformationBarOp::Message(pMessage); 00187 } 00188 00189 // Does this message mean that the selected object has changed, or its attributes (bounds)? 00190 if (pMessage->IsKindOf(CC_RUNTIME_CLASS(SelChangingMsg))) 00191 { 00192 if (pSelectorTool != NULL) 00193 { 00194 switch (((SelChangingMsg*) pMessage)->State) 00195 { 00196 case SelChangingMsg::SELECTIONCHANGED: 00197 if (!pSelectorTool->fIgnoreSelChange) pSelectorTool->SelectionHasChanged(); 00198 break; 00199 00200 case SelChangingMsg::NONCOLOURATTCHANGED: 00201 pSelectorTool->AttributeHasChanged(); 00202 break; 00203 00204 default: 00205 break; 00206 } 00207 } 00208 } 00209 00210 // How about a view changing message? 00211 else if (MESSAGE_IS_A(pMessage, DocViewMsg)) 00212 { 00213 // Yes, tell the selector tool to sort its blobs out. 00214 if (pSelectorTool != NULL) 00215 { 00216 pSelectorTool->ViewChanged(*((DocViewMsg*) pMessage)); 00217 } 00218 } 00219 00220 // Or an options-changing message? 00221 else if (MESSAGE_IS_A(pMessage, OptionsChangingMsg)) 00222 { 00223 // Yes, so force the edit-fields to reconvert themselves to the new settings. 00224 TRACEUSER( "JustinF", _T("Updating on options-change in selector tool info-bar\n")); 00225 SetEdit_OnSelectionChange(); 00226 } 00227 00228 // Otherwise, is this a dialog message for us? 00229 else if (IS_OUR_DIALOG_MSG(pMessage)) 00230 { 00231 // Yes. Act on the dialog message. 00232 DialogMsg* pDlgMsg = (DialogMsg*) pMessage; 00233 switch (pDlgMsg->DlgMsg) 00234 { 00235 // Initialise the bar's controls. 00236 case DIM_CREATE: 00237 HandleCreate(pDlgMsg); 00238 break; 00239 00240 // "Close" the bar. 00241 case DIM_CANCEL: 00242 SelectorTool::UnCacheInfoBar(TRUE); 00243 break; 00244 00245 // Handle a button being clicked. 00246 case DIM_LFT_BN_CLICKED: 00247 if (!HandleButtonDown(pDlgMsg)) return DialogBarOp::Message(pMessage); 00248 break; 00249 00250 // Handle a button being released. 00251 case DIM_LFT_BN_UP: 00252 HandleButtonUp(pDlgMsg); 00253 break; 00254 00255 // Handle ENTER being typed in an edit field. 00256 case DIM_SELECTION_CHANGED: 00257 HandleEditCommit(pDlgMsg); 00258 break; 00259 00260 // Handle a "telephone keypad" button message. 00261 case DIM_GRID_BUTTON_DOWN: 00262 HandleGridButton(pDlgMsg); 00263 break; 00264 00265 // Some other message irrelevant to us. 00266 default: 00267 break; 00268 } 00269 } 00270 00271 // Pass message on to base class. 00272 return InformationBarOp::Message(pMessage); 00273 } 00274 00275 00276 00277 /******************************************************************************************** 00278 > BOOL SelectorInfoBarOp::IsAspectLocked() const 00279 00280 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00281 Created: 31/8/94 00282 Inputs: - 00283 Outputs: - 00284 Returns: TRUE if the "Lock Aspect Ratio" button is down. 00285 Purpose: Enquires of the state of the "Lock Aspect Ratio" button. 00286 Errors: - 00287 SeeAlso: - 00288 ********************************************************************************************/ 00289 00290 BOOL SelectorInfoBarOp::IsAspectLocked() const 00291 { 00292 return fLockAspect; 00293 } 00294 00295 00296 00297 /******************************************************************************************** 00298 > BOOL SelectorInfoBarOp::InRotateMode() const 00299 00300 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00301 Created: 31/8/94 00302 Inputs: - 00303 Outputs: - 00304 Returns: TRUE if the "Rotate/Bounds blobs" button is down. 00305 Purpose: Checks the state of the "Rotate/Bounds blobs" button. 00306 Errors: - 00307 SeeAlso: - 00308 ********************************************************************************************/ 00309 00310 BOOL SelectorInfoBarOp::InRotateMode() const 00311 { 00312 return fRotateMode; 00313 } 00314 00315 00316 00317 /******************************************************************************************** 00318 > BOOL SelectorInfoBarOp::ShouldLeaveCopy() const 00319 00320 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00321 Created: 31/8/94 00322 Inputs: - 00323 Outputs: - 00324 Returns: TRUE if the "Leave Copy" button is down. 00325 Purpose: Checks the state of the "Leave Copy" button. 00326 Errors: - 00327 SeeAlso: - 00328 ********************************************************************************************/ 00329 /* 00330 BOOL SelectorInfoBarOp::ShouldLeaveCopy() const 00331 { 00332 return fLeaveCopy; 00333 } 00334 */ 00335 00336 00337 /******************************************************************************************** 00338 > BOOL SelectorInfoBarOp::ShouldScaleLines() const 00339 00340 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00341 Created: 31/8/94 00342 Inputs: - 00343 Outputs: - 00344 Returns: TRUE if the "Scale Lines" button is down. 00345 Purpose: Checks the state of the "Scale Lines" button. 00346 Errors: - 00347 SeeAlso: - 00348 ********************************************************************************************/ 00349 00350 BOOL SelectorInfoBarOp::ShouldScaleLines() const 00351 { 00352 return fScaleLines; 00353 } 00354 00355 00356 00357 /******************************************************************************************** 00358 00359 > BOOL SelectorInfoBarOp::DontConsiderAttrs(void) const 00360 00361 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00362 Created: 26/2/96 00363 Returns: TRUE if attributes should NOT be considered in width/height displays 00364 00365 Purpose: Checks the "DontConsiderAttrs" state. 00366 This is used to determine if displays and editing of widths and heights 00367 of objects should include the effect of attributes - for example, line 00368 widths can significantly affect the size of an object. 00369 00370 Notes: Depending on the user preferences, this option is either slaved off the 00371 "Scale Line Widths" option, or is forced on/off permanently. 00372 00373 The preferences controlling this behaviour are held in the SelectorTool 00374 00375 ********************************************************************************************/ 00376 00377 BOOL SelectorInfoBarOp::DontConsiderAttrs(void) const 00378 { 00379 // If "SlaveLineWidthToButton" preference is TRUE, then we use the Scale Line Widths 00380 // button state to determine the return value 00381 if (SelectorTool::fSlaveLineWidthToButton) 00382 return(!ShouldScaleLines()); 00383 00384 // Otherwise, we take the setting from the "ConsiderLineWidths" preference 00385 return(!SelectorTool::fConsiderLineWidths); 00386 } 00387 00388 00389 00390 /******************************************************************************************** 00391 > BOOL SelectorInfoBarOp::ShouldTransFills() const 00392 00393 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00394 Created: 31/8/94 00395 Inputs: - 00396 Outputs: - 00397 Returns: TRUE if the "Transform Fills" button is down. 00398 Purpose: Checks the state of the "Scale Lines" button. NB. FEATURE REMOVED FOR 00399 THIS RELEASE. 00400 Errors: - 00401 SeeAlso: - 00402 ********************************************************************************************/ 00403 /* 00404 BOOL SelectorInfoBarOp::ShouldTransFills() const 00405 { 00406 return fTransFills; 00407 } 00408 */ 00409 00410 00411 /******************************************************************************************** 00412 > void SelectorInfoBarOp::SetAspectLock(BOOL fState) 00413 00414 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00415 Created: 31/8/94 00416 Inputs: fState the new state of the "Lock Aspect Ratio" button (TRUE = down) 00417 Outputs: - 00418 Returns: - 00419 Purpose: Sets the state of the "Lock Aspect Ratio" button. 00420 Errors: - 00421 SeeAlso: - 00422 ********************************************************************************************/ 00423 00424 void SelectorInfoBarOp::SetAspectLock(BOOL fState) 00425 { 00426 if(HasWindow()) 00427 SetLongGadgetValue(_R(IDC_SEL_PADLOCK), (fLockAspect = fState), FALSE); 00428 } 00429 00430 00431 00432 /******************************************************************************************** 00433 > void SelectorInfoBarOp::SetRotateMode(BOOL fState) 00434 00435 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00436 Created: 31/8/94 00437 Inputs: fState TRUE if the button should be down 00438 Outputs: - 00439 Returns: - 00440 Purpose: Sets the state of the "Rotate/Bounds blobs" button. 00441 Errors: - 00442 SeeAlso: - 00443 ********************************************************************************************/ 00444 00445 void SelectorInfoBarOp::SetRotateMode(BOOL fState) 00446 { 00447 fRotateMode = fState; 00448 if (HasWindow()) SetLongGadgetValue(_R(IDC_SEL_ROTATEBUTTON), fState, FALSE); 00449 } 00450 00451 00452 00453 /******************************************************************************************** 00454 > void SelectorInfoBarOp::SetLeaveCopy(BOOL fState) 00455 00456 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00457 Created: 31/8/94 00458 Inputs: fState TRUE if the button should be down 00459 Outputs: - 00460 Returns: - 00461 Purpose: Sets the state of the "Leave Copy" button. 00462 Errors: - 00463 SeeAlso: - 00464 ********************************************************************************************/ 00465 /* 00466 void SelectorInfoBarOp::SetLeaveCopy(BOOL fState) 00467 { 00468 fLeaveCopy = fState; 00469 if (HasWindow()) SetLongGadgetValue(_R(IDC_SEL_LEAVECOPY), fLeaveCopy, FALSE); 00470 } 00471 */ 00472 00473 00474 /******************************************************************************************** 00475 > void SelectorInfoBarOp::SetScaleLines(BOOL fState) 00476 00477 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00478 Created: 31/8/94 00479 Inputs: fState TRUE if the button should be down 00480 Outputs: - 00481 Returns: - 00482 Purpose: Sets the state of the "Scale Lines" button. 00483 Errors: - 00484 SeeAlso: - 00485 ********************************************************************************************/ 00486 00487 void SelectorInfoBarOp::SetScaleLines(BOOL fState) 00488 { 00489 if (HasWindow()) 00490 { 00491 SetLongGadgetValue(_R(IDC_SEL_SCALELINES), (fScaleLines = fState), FALSE); 00492 00493 // Make sure that the selector tool is displaying the correct information for 00494 // the new button state (which can affect the displayed size of the selection) 00495 if (pSelectorTool) 00496 pSelectorTool->SelectionHasChanged(); 00497 } 00498 00499 } 00500 00501 00502 00503 /******************************************************************************************** 00504 > void SelectorInfoBarOp::SetTransFills(BOOL fState) 00505 00506 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00507 Created: 31/8/94 00508 Inputs: fState TRUE if the button should be down 00509 Outputs: - 00510 Returns: - 00511 Purpose: Sets the state of the "Transform Fills" button. NB. FEATURE REMOVED FOR 00512 THIS RELEASE. 00513 Errors: - 00514 SeeAlso: - 00515 ********************************************************************************************/ 00516 /* 00517 void SelectorInfoBarOp::SetTransFills(BOOL fState) 00518 { 00519 SetLongGadgetValue(_R(IDC_SEL_TRANSFILL), (fTransFills = fState), FALSE); 00520 } 00521 */ 00522 00523 00524 /******************************************************************************************** 00525 > SelEditRecord* SelectorInfoBarOp::GetRecord(UINT32 nEditControlID) 00526 00527 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00528 Created: 4/11/94 00529 Inputs: - 00530 Outputs: - 00531 Returns: - 00532 Purpose: 00533 Errors: - 00534 SeeAlso: - 00535 ********************************************************************************************/ 00536 00537 SelEditRecord* SelectorInfoBarOp::GetRecord(UINT32 nEditControlID) 00538 { 00539 if (!HasWindow()) return NULL; 00540 00541 // Search through the array of edit-records lloking for the given ID. 00542 for (SelEditRecord* per = aerEdits; per < &aerEdits[8]; per++) 00543 { 00544 if (per->nControlID == nEditControlID) return per; 00545 } 00546 00547 // Couldn't find the corresponding edit-field (big problem!) 00548 ERROR3("Couldn't find edit-field record in SelectorInfoBarOp::GetRecord!"); 00549 return NULL; 00550 } 00551 00552 00553 00554 /******************************************************************************************** 00555 > void SelectorInfoBarOp::UpdateRecord(SelEditRecord* pefr) 00556 00557 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00558 Created: 4/11/94 00559 Inputs: pefr --- pointer to the edit-field record to be updated 00560 Outputs: - 00561 Returns: - 00562 Purpose: Called when an edit-field is initialised or changed by the user. 00563 Errors: - 00564 SeeAlso: - 00565 ********************************************************************************************/ 00566 00567 void SelectorInfoBarOp::UpdateRecord(SelEditRecord* per) 00568 { 00569 if (per) 00570 { 00571 // Copy the text in the edit field. 00572 BOOL fOk = TRUE; 00573 if (HasWindow()) 00574 { 00575 per->strText = GetStringGadgetValue(per->nControlID, &fOk); 00576 if (!fOk) 00577 { 00578 TRACEUSER( "JustinF", _T("Couldn't update edit-field %u\n"), per->nControlID); 00579 per->strText = TEXT(""); 00580 } 00581 } 00582 else 00583 { 00584 per->strText = TEXT(""); 00585 } 00586 } 00587 } 00588 00589 00590 00591 /******************************************************************************************** 00592 > void SelectorInfoBarOp::UpdateRecord(UINT32 nControlID) 00593 00594 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00595 Created: 16/11/94 00596 Inputs: nControlID resource ID the edit-control 00597 Outputs: - 00598 Returns: - 00599 Purpose: Updates internal records of the given edit-control 00600 Errors: - 00601 SeeAlso: - 00602 ********************************************************************************************/ 00603 00604 void SelectorInfoBarOp::UpdateRecord(UINT32 nControlID) 00605 { 00606 UpdateRecord(GetRecord(nControlID)); 00607 } 00608 00609 00610 00611 /******************************************************************************************** 00612 > void SelectorInfoBarOp::UpdateAllRecords() 00613 00614 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00615 Created: 16/11/94 00616 Inputs: - 00617 Outputs: - 00618 Returns: - 00619 Purpose: Updates internal records of all edit-controls. 00620 Errors: - 00621 SeeAlso: - 00622 ********************************************************************************************/ 00623 00624 void SelectorInfoBarOp::UpdateAllRecords() 00625 { 00626 for (SelEditRecord* per = aerEdits; per < &aerEdits[8]; per++) 00627 { 00628 UpdateRecord(per); 00629 } 00630 } 00631 00632 00633 00634 /******************************************************************************************** 00635 > BOOL SelectorInfoBarOp::HasChangedRecord(INT32 i) 00636 00637 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00638 Created: 16/11/94 00639 Inputs: i 0 - 7, identifying which edit-control to report on. 00640 Outputs: - 00641 Returns: TRUE if edit-control [i] has been changed recently by the user 00642 Purpose: Reports on whether the given edit-control has new info in it. 00643 Errors: - 00644 SeeAlso: - 00645 ********************************************************************************************/ 00646 00647 BOOL SelectorInfoBarOp::HasChangedRecord(INT32 i) 00648 { 00649 // Copy the text in the edit field. 00650 SelEditRecord* per = &aerEdits[i]; 00651 BOOL fOk; 00652 String_256 str; 00653 if(HasWindow()) 00654 str = GetStringGadgetValue(per->nControlID, &fOk); 00655 else 00656 fOk = FALSE; 00657 00658 if (!fOk) 00659 { 00660 TRACEUSER( "JustinF", _T("Couldn't test edit-field %u\n"), per->nControlID ); 00661 return per->fIsDirty = FALSE; 00662 } 00663 00664 // Compare the existing text with the old record. 00665 return per->fIsDirty = (str != per->strText); 00666 } 00667 00668 00669 00670 /******************************************************************************************** 00671 > double SelectorInfoBarOp::ConvertRecord(INT32 i) 00672 00673 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00674 Created: 16/11/94 00675 Inputs: i identifier of an edit-control, 0-7 00676 Outputs: - 00677 Returns: The numeric value of the contents of the edit-control. 00678 Purpose: Reads the text in the given edit-control record and converts it to a INT32. 00679 Errors: - 00680 SeeAlso: - 00681 ********************************************************************************************/ 00682 00683 double SelectorInfoBarOp::ConvertRecord(INT32 i) 00684 { 00685 double n; 00686 fConvertedOK = fConvertedOK && Convert::StringToDouble( aerEdits[i].strText, &n ); 00687 return n; 00688 } 00689 00690 00691 00692 /******************************************************************************************** 00693 > MILLIPOINT SelectorInfoBarOp::ConvertMillipointRecord(INT32 i) 00694 00695 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00696 Created: 16/11/94 00697 Inputs: i identifier of an edit-control, 0-7 00698 Outputs: - 00699 Returns: The contents of the given edit-control as a millipoint value. 00700 Purpose: Converts an edit-control to a millipoint value, allowing for unit conversions. 00701 Errors: - 00702 SeeAlso: - 00703 ********************************************************************************************/ 00704 00705 MILLIPOINT SelectorInfoBarOp::ConvertMillipointRecord(INT32 i) 00706 { 00707 MILLIPOINT n; 00708 DimScale* pDimScale = DimScale::GetPtrDimScale(pSelectorTool->GetSelectionSpread()); 00709 ERROR2IF (pDimScale == NULL, 1, 00710 "Null DimScale* in SelectorInfoBarOp::ConvertMillipointRecord"); 00711 fConvertedOK = fConvertedOK && pDimScale->ConvertToMillipoints( aerEdits[i].strText, &n ); 00712 return n; 00713 } 00714 00715 00716 00717 /******************************************************************************************** 00718 > FIXED16 SelectorInfoBarOp::ConvertFixedpointRecord(INT32 i) 00719 00720 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00721 Created: 16/11/94 00722 Inputs: i edit-control identifier, 0-7 00723 Outputs: - 00724 Returns: Contents of the edit-control as a fixed-point number 00725 Purpose: Converts the given edit-control to a fixed-point number 00726 Errors: - 00727 SeeAlso: - 00728 ********************************************************************************************/ 00729 00730 FIXED16 SelectorInfoBarOp::ConvertFixedpointRecord(INT32 i) 00731 { 00732 BOOL fOk; 00733 double n = Convert::StringToDouble( aerEdits[i].strText, MILLIPOINTS, &fOk ); // NB. not really 00734 fConvertedOK = fConvertedOK && fOk; 00735 return (FIXED16) n; 00736 } 00737 00738 00739 00740 /******************************************************************************************** 00741 > void SelectorInfoBarOp::SetEdit(CGadgetID gid, INT32 nValue, Spread* pUnitSpread, 00742 BOOL fUpdate = TRUE) 00743 00744 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00745 Created: 31/8/94 00746 Inputs: gid gadget identifier 00747 nValue the value to set in the edit field (INT32 integer) 00748 pUnitSpread the spread containing the object (so its units can be 00749 extracted). If this parameter is NULL then no unit 00750 conversion is performed. 00751 fUpdate update the internal records of the field's contents if 00752 TRUE (the default). 00753 Outputs: - 00754 Returns: - 00755 Purpose: Converts the given value to the appropriate units, as contained in the 00756 spread, converts it to text and writes in into the edit-field. 00757 Errors: - 00758 SeeAlso: SelectorInfoBarOp::SetEdit_OnDrag; 00759 SelectorInfoBarOp::SetEdit_OnSelectionChange 00760 ********************************************************************************************/ 00761 00762 void SelectorInfoBarOp::SetEdit(CGadgetID gid, INT32 nValue, Spread* pUnitSpread, BOOL fUpdate) 00763 { 00764 if (pUnitSpread != NULL) 00765 { 00766 // Get the dimension scaling object (units) associated with the given spread 00767 // and convert to its units. 00768 DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) pUnitSpread); 00769 ENSURE(pDimScale != NULL, "Null DimScale* in SelectorInfoBarOp::SetEdit"); 00770 00771 // Convert to units & text and display. 00772 String_256 str; 00773 pDimScale->ConvertToUnits((INT32) nValue, &str); 00774 if (HasWindow()) SetStringGadgetValue(gid, str); 00775 } 00776 else 00777 { 00778 // No unit conversion necessary, just convert to text. 00779 if (HasWindow()) SetLongGadgetValue(gid, nValue); 00780 } 00781 00782 // Grab the text for our records, if required. 00783 if (fUpdate) UpdateRecord((UINT32) gid); 00784 } 00785 00786 00787 00788 /******************************************************************************************** 00789 > void SelectorInfoBarOp::SetDoubleEdit(CGadgetID gid, double nValue, BOOL fUpdate = TRUE) 00790 00791 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00792 Created: 23/2/95 00793 Inputs: gid gadget identifier 00794 nValue the value to set in the edit field (INT32 integer) 00795 fUpdate update the internal records of the field's contents if 00796 TRUE (the default). 00797 Outputs: - 00798 Returns: - 00799 Purpose: Converts the given double value to text and writes in into the edit-field. 00800 Errors: - 00801 SeeAlso: SelectorInfoBarOp::SetEdit; 00802 SelectorInfoBarOp::SetEdit_OnDrag; 00803 SelectorInfoBarOp::SetEdit_OnSelectionChange 00804 ********************************************************************************************/ 00805 00806 void SelectorInfoBarOp::SetDoubleEdit(CGadgetID gid, double nValue, BOOL fUpdate) 00807 { 00808 // No unit conversion necessary, just convert to text. 00809 if (HasWindow()) SetDoubleGadgetValue(gid, nValue); 00810 00811 // Grab the text for our records, if required. 00812 if (fUpdate) UpdateRecord((UINT32) gid); 00813 } 00814 00815 00816 00817 /******************************************************************************************** 00818 > void SelectorInfoBarOp::SetEdit(CGadgetID gid, FIXED16 fxValue, Spread* pUnitSpread, 00819 BOOL fUpdate = TRUE) 00820 00821 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00822 Created: 5/9/94 00823 Inputs: gid the edit-field gadget (control) identifier that is to be set 00824 fxValue the fixed-point value to set in the field 00825 pUnitSpread the spread that is used for unit conversions. If null then 00826 no unit conversion will occur (CURRENTLY NOT SUPPORTED). 00827 Outputs: - 00828 Returns: - 00829 Purpose: Sets an edit-field in the selector info-bar to the given fixed-point 00830 value. If a spread is passed then the value will be converted to the 00831 appropriate units for the spread. Currently ANGLEs are always in degrees 00832 so this is not yet implemented. 00833 Errors: - 00834 SeeAlso: - 00835 ********************************************************************************************/ 00836 00837 void SelectorInfoBarOp::SetEdit(CGadgetID gid, FIXED16 fxValue, Spread* pUnitSpread, 00838 BOOL fUpdate) 00839 { 00840 /* if (pUnitSpread != NULL && IsUserName("JustinF")) 00841 { 00842 TRACE( _T("Warning - non-null pUnitSpread in SelectorInfoBarOp::SetEdit\n")); 00843 } 00844 */ 00845 String str; 00846 fxValue.ToString(&str); 00847 if (HasWindow()) SetStringGadgetValue(gid, str, FALSE); 00848 if (fUpdate) UpdateRecord((UINT32) gid); 00849 } 00850 00851 00852 00853 /******************************************************************************************** 00854 > void SelectorInfoBarOp::ClearEdit(CGadgetID gid) 00855 00856 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00857 Created: 5/9/94 00858 Inputs: gid the gadget ID of the edit-field to clear 00859 Outputs: - 00860 Returns: - 00861 Purpose: Blanks the given edit-field. 00862 Errors: - 00863 SeeAlso: - 00864 ********************************************************************************************/ 00865 00866 void SelectorInfoBarOp::ClearEdit(CGadgetID gid) 00867 { 00868 String_256 str; 00869 str.Empty(); 00870 if(HasWindow()) 00871 SetStringGadgetValue(gid, str, FALSE); 00872 UpdateRecord((UINT32) gid); 00873 } 00874 00875 00876 00877 /******************************************************************************************** 00878 > void SelectorInfoBarOp::EnableAllEdits(BOOL fEnabled) 00879 00880 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00881 Created: 31/8/94 00882 Inputs: fEnabled TRUE if the gadgets should be enabled, FALSE if they 00883 should be disabled. 00884 Outputs: - 00885 Returns: - 00886 Purpose: Enables or disables the edit-fields in the info-bar, 00887 clearing them to blank if they are being disabled. 00888 Errors: - 00889 SeeAlso: - 00890 ********************************************************************************************/ 00891 00892 void SelectorInfoBarOp::EnableAllEdits(BOOL fEnabled) 00893 { 00894 if (!HasWindow()) 00895 { 00896 TRACEUSER( "JustinF", _T("Tried to enable edit controls but they don't exist?!?\n")); 00897 return; 00898 } 00899 00900 // Clear the edit fields if being disabled. 00901 if (!fEnabled) 00902 { 00903 ClearEdit(_R(IDC_SEL_EDIT_X)); 00904 ClearEdit(_R(IDC_SEL_EDIT_Y)); 00905 ClearEdit(_R(IDC_SEL_EDIT_W)); 00906 ClearEdit(_R(IDC_SEL_EDIT_H)); 00907 ClearEdit(_R(IDC_SEL_EDIT_XSCALE)); 00908 ClearEdit(_R(IDC_SEL_EDIT_YSCALE)); 00909 ClearEdit(_R(IDC_SEL_EDIT_ANGLE)); 00910 ClearEdit(_R(IDC_SEL_EDIT_SHEAR)); 00911 } 00912 00913 // Enable/disable the controls. 00914 EnableGadget(_R(IDC_SEL_EDIT_X), fEnabled); 00915 EnableGadget(_R(IDC_SEL_EDIT_Y), fEnabled); 00916 EnableGadget(_R(IDC_SEL_EDIT_W), fEnabled); 00917 EnableGadget(_R(IDC_SEL_EDIT_H), fEnabled); 00918 EnableGadget(_R(IDC_SEL_EDIT_XSCALE), fEnabled); 00919 EnableGadget(_R(IDC_SEL_EDIT_YSCALE), fEnabled); 00920 EnableGadget(_R(IDC_SEL_EDIT_ANGLE), fEnabled); 00921 EnableGadget(_R(IDC_SEL_EDIT_SHEAR), fEnabled); 00922 } 00923 00924 /******************************************************************************************** 00925 > void SelectorInfoBarOp::EnableGrid(BOOL fEnabled) 00926 00927 Author: Alex Bligh <alex@alex.org.uk> 00928 Created: 03-Feb-2005 00929 Inputs: fEnabled TRUE if the gadgets should be enabled, FALSE if they 00930 should be disabled. 00931 Outputs: - 00932 Returns: - 00933 Purpose: Enables or disables the rotate grid control 00934 Errors: - 00935 SeeAlso: - 00936 ********************************************************************************************/ 00937 00938 void SelectorInfoBarOp::EnableGrid(BOOL fEnabled) 00939 { 00940 EnableGadget(_R(IDC_SEL_GRID_NW), fEnabled); 00941 EnableGadget(_R(IDC_SEL_GRID_N) , fEnabled); 00942 EnableGadget(_R(IDC_SEL_GRID_NE), fEnabled); 00943 EnableGadget(_R(IDC_SEL_GRID_W) , fEnabled); 00944 EnableGadget(_R(IDC_SEL_GRID_CENTRE), fEnabled); 00945 EnableGadget(_R(IDC_SEL_GRID_E) , fEnabled); 00946 EnableGadget(_R(IDC_SEL_GRID_SW), fEnabled); 00947 EnableGadget(_R(IDC_SEL_GRID_S) , fEnabled); 00948 EnableGadget(_R(IDC_SEL_GRID_SE), fEnabled); 00949 } 00950 00951 /******************************************************************************************** 00952 > void SelectorInfoBarOp::PaintAllEditsNow() 00953 00954 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00955 Created: 5/9/94 00956 Inputs: - 00957 Outputs: - 00958 Returns: - 00959 Purpose: Forces an immediate repaint of any edit field that has had its contents 00960 changed. 00961 Errors: - 00962 SeeAlso: - 00963 ********************************************************************************************/ 00964 00965 void SelectorInfoBarOp::PaintAllEditsNow() 00966 { 00967 if (!HasWindow()) return; 00968 PaintGadgetNow(_R(IDC_SEL_EDIT_X)); 00969 PaintGadgetNow(_R(IDC_SEL_EDIT_Y)); 00970 PaintGadgetNow(_R(IDC_SEL_EDIT_W)); 00971 PaintGadgetNow(_R(IDC_SEL_EDIT_H)); 00972 PaintGadgetNow(_R(IDC_SEL_EDIT_XSCALE)); 00973 PaintGadgetNow(_R(IDC_SEL_EDIT_YSCALE)); 00974 PaintGadgetNow(_R(IDC_SEL_EDIT_ANGLE)); 00975 PaintGadgetNow(_R(IDC_SEL_EDIT_SHEAR)); 00976 } 00977 00978 00979 00980 /******************************************************************************************** 00981 > void SelectorInfoBarOp::SetEdit_OnSelectionChange() 00982 00983 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00984 Created: 31/8/94 00985 Inputs: - 00986 Outputs: - 00987 Returns: - 00988 Purpose: Updates the X, Y, W, H edit fields of the info-bar with the position and 00989 extent of the currently selected object(s), if any. If there is no 00990 selection then it clears and disables the edit-fields until there is. 00991 Called by the selector tool when it is notified that the selection has 00992 changed. 00993 00994 Now also greys/ungreys info-bar buttons, as appropriate. 00995 Errors: - 00996 SeeAlso: - 00997 ********************************************************************************************/ 00998 00999 void SelectorInfoBarOp::SetEdit_OnSelectionChange() 01000 { 01001 if (!HasWindow()) 01002 { 01003 // TRACEUSER( "JustinF", _T("Tried to set edits on selection change but they don't exist?!?\n")); 01004 return; 01005 } 01006 01007 Spread* pSpread = pSelectorTool->GetSelectionSpread(); 01008 if (pSpread != NULL) 01009 { 01010 // Get extent of new selection in user coords, and Update all the numeric gadgets. 01011 DocRect DRSelExtent = pSelectorTool->GetSelectionBounds(DontConsiderAttrs()); 01012 UserRect SelExtent = DRSelExtent.ToUser(pSpread); 01013 SetEdit(_R(IDC_SEL_EDIT_X), SelExtent.lo.x, pSpread); 01014 SetEdit(_R(IDC_SEL_EDIT_Y), SelExtent.lo.y, pSpread); 01015 SetEdit(_R(IDC_SEL_EDIT_W), SelExtent.Width(), pSpread); 01016 SetEdit(_R(IDC_SEL_EDIT_H), SelExtent.Height(), pSpread); 01017 SetEdit(_R(IDC_SEL_EDIT_XSCALE), (FIXED16) 100, NULL); 01018 SetEdit(_R(IDC_SEL_EDIT_YSCALE), (FIXED16) 100, NULL); 01019 SetEdit(_R(IDC_SEL_EDIT_ANGLE), (FIXED16) 0, NULL); 01020 SetEdit(_R(IDC_SEL_EDIT_SHEAR), (FIXED16) 0, NULL); 01021 01022 // Ungrey the buttons that are now available. 01023 EnableGadget(_R(IDC_SEL_BUMP_X_LESS), TRUE); 01024 EnableGadget(_R(IDC_SEL_BUMP_X_MORE), TRUE); 01025 EnableGadget(_R(IDC_SEL_BUMP_Y_LESS), TRUE); 01026 EnableGadget(_R(IDC_SEL_BUMP_Y_MORE), TRUE); 01027 EnableGadget(_R(IDC_SEL_BUMP_W_LESS), TRUE); 01028 EnableGadget(_R(IDC_SEL_BUMP_W_MORE), TRUE); 01029 EnableGadget(_R(IDC_SEL_BUMP_H_LESS), TRUE); 01030 EnableGadget(_R(IDC_SEL_BUMP_H_MORE), TRUE); 01031 EnableGadget(_R(IDC_SEL_BUMP_ANGLE_LESS), TRUE); 01032 EnableGadget(_R(IDC_SEL_BUMP_ANGLE_MORE), TRUE); 01033 EnableGadget(_R(IDC_SEL_BUMP_SHEAR_LESS), TRUE); 01034 EnableGadget(_R(IDC_SEL_BUMP_SHEAR_MORE), TRUE); 01035 EnableGadget(_R(IDC_SEL_FLIPHORZ), TRUE); 01036 EnableGadget(_R(IDC_SEL_FLIPVERT), TRUE); 01037 // EnableGadget(_R(IDC_SEL_ROTATE_GRID), TRUE); 01038 EnableGrid(TRUE); 01039 01040 // Reenable the edit-controls. 01041 EnableAllEdits(TRUE); 01042 } 01043 else 01044 { 01045 // Disable all the edit-controls and blank them. 01046 EnableAllEdits(FALSE); 01047 01048 // Grey the buttons that are now unavailable. 01049 EnableGadget(_R(IDC_SEL_BUMP_X_LESS), FALSE); 01050 EnableGadget(_R(IDC_SEL_BUMP_X_MORE), FALSE); 01051 EnableGadget(_R(IDC_SEL_BUMP_Y_LESS), FALSE); 01052 EnableGadget(_R(IDC_SEL_BUMP_Y_MORE), FALSE); 01053 EnableGadget(_R(IDC_SEL_BUMP_W_LESS), FALSE); 01054 EnableGadget(_R(IDC_SEL_BUMP_W_MORE), FALSE); 01055 EnableGadget(_R(IDC_SEL_BUMP_H_LESS), FALSE); 01056 EnableGadget(_R(IDC_SEL_BUMP_H_MORE), FALSE); 01057 EnableGadget(_R(IDC_SEL_BUMP_ANGLE_LESS), FALSE); 01058 EnableGadget(_R(IDC_SEL_BUMP_ANGLE_MORE), FALSE); 01059 EnableGadget(_R(IDC_SEL_BUMP_SHEAR_LESS), FALSE); 01060 EnableGadget(_R(IDC_SEL_BUMP_SHEAR_MORE), FALSE); 01061 EnableGadget(_R(IDC_SEL_FLIPHORZ), FALSE); 01062 EnableGadget(_R(IDC_SEL_FLIPVERT), FALSE); 01063 // EnableGadget(_R(IDC_SEL_ROTATE_GRID), FALSE); 01064 EnableGrid(FALSE); 01065 } 01066 } 01067 01068 01069 01070 /******************************************************************************************** 01071 > void SelectorInfoBarOp::SetEdit_OnDrag(TransformBoundingData* pData, Spread* pSpread) 01072 01073 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01074 Created: 31/8/94 01075 Inputs: pData pointer to the "callback" data generated by mouse-drags, 01076 containing a description of the dragged object's extent etc. 01077 Outputs: - 01078 Returns: - 01079 Purpose: Dynamically updates the text in the edit-fields as an object is being 01080 dragged. Works out what needs doing from the pData argument. 01081 Errors: - 01082 SeeAlso: SelectorTool::DragMove 01083 ********************************************************************************************/ 01084 01085 void SelectorInfoBarOp::SetEdit_OnDrag(TransformBoundingData* pData, Spread* pSpread) 01086 { 01087 // Make sure the info-bar hasn't been hidden. 01088 if (!HasWindow()) return; 01089 01090 if (pData->XYChanged) 01091 { 01092 // Convert the spread coords to user coords, and update gadgets 01093 UserCoord UserPos = DocCoord(pData->x, pData->y).ToUser(pSpread); 01094 SetEdit(_R(IDC_SEL_EDIT_X), UserPos.x, pSpread); 01095 SetEdit(_R(IDC_SEL_EDIT_Y), UserPos.y, pSpread); 01096 PaintGadgetNow(_R(IDC_SEL_EDIT_X)); 01097 PaintGadgetNow(_R(IDC_SEL_EDIT_Y)); 01098 pData->XYChanged = FALSE; 01099 } 01100 01101 if (pData->WHChanged) 01102 { 01103 SetEdit(_R(IDC_SEL_EDIT_W), pData->Width, pSpread); 01104 SetEdit(_R(IDC_SEL_EDIT_H), pData->Height, pSpread); 01105 PaintGadgetNow(_R(IDC_SEL_EDIT_W)); 01106 PaintGadgetNow(_R(IDC_SEL_EDIT_H)); 01107 pData->WHChanged = FALSE; 01108 } 01109 01110 if (pData->ScaleChanged) 01111 { 01112 // Take the absolute value and round to the nearest percent. 01113 FIXED16 xfx = (pData->XScale < 0) ? -pData->XScale : pData->XScale; 01114 FIXED16 yfx = (pData->YScale < 0) ? -pData->YScale : pData->YScale; 01115 INT32 xs = (xfx * 100 + FIXED16(0.5)).MakeLong(); 01116 INT32 ys = (yfx * 100 + FIXED16(0.5)).MakeLong(); 01117 SetEdit(_R(IDC_SEL_EDIT_XSCALE), xs, NULL); 01118 SetEdit(_R(IDC_SEL_EDIT_YSCALE), ys, NULL); 01119 PaintGadgetNow(_R(IDC_SEL_EDIT_XSCALE)); 01120 PaintGadgetNow(_R(IDC_SEL_EDIT_YSCALE)); 01121 pData->ScaleChanged = FALSE; 01122 } 01123 01124 if (pData->RotateChanged) 01125 { 01126 SetEdit(_R(IDC_SEL_EDIT_ANGLE), pData->Rotation, pSpread); 01127 PaintGadgetNow(_R(IDC_SEL_EDIT_ANGLE)); 01128 pData->RotateChanged = FALSE; 01129 } 01130 01131 if (pData->ShearChanged) 01132 { 01133 double ShearAngle = pData->Shear.MakeDouble(); 01134 01135 // First we muct ensure that the displayed angle is in the -90..+90 range - 01136 // The angles coming in will either be centered around 0 or 180 degrees. 01137 // We therefore move them all to the 0 origin, so that they are displayed correctly 01138 if (ShearAngle >= 90.0) 01139 ShearAngle = -180.0 + ShearAngle; 01140 01141 if (ShearAngle <= -90.0) 01142 ShearAngle = 180.0 + ShearAngle; 01143 01144 // And ensure they lie in a sensible range 01145 if (ShearAngle < -89.0) 01146 ShearAngle = -89.0; 01147 01148 if (ShearAngle > 89.0) 01149 ShearAngle = 89.0; 01150 01151 SetEdit(_R(IDC_SEL_EDIT_SHEAR), (ANGLE) ShearAngle, pSpread); 01152 PaintGadgetNow(_R(IDC_SEL_EDIT_SHEAR)); 01153 pData->ShearChanged = FALSE; 01154 } 01155 01156 if (pData->ScaleLinesChanged) 01157 { 01158 SetScaleLines(pData->ScaleLines); 01159 PaintGadgetNow(_R(IDC_SEL_SCALELINES)); 01160 pData->ScaleLinesChanged = FALSE; 01161 } 01162 01163 // Make sure all changes are immediately visible. 01164 // PaintAllEditsNow(); 01165 } 01166 01167 01168 01169 /******************************************************************************************** 01170 > void SelectorInfoBarOp::HandleCreate(DialogMsg* pDlgMsg) 01171 01172 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01173 Created: 13/7/94 01174 Inputs: A pointer to the DIM_CREATE dialog message to handle (not used) 01175 Purpose: Sets the initial state of the controls in the info-bar. 01176 SeeAlso: SelectorInfoBarOp::Message 01177 ********************************************************************************************/ 01178 01179 void SelectorInfoBarOp::HandleCreate(DialogMsg* /* pDlgMsg */) 01180 { 01181 // TRACEUSER( "JustinF", _T("In SelectorInfoBarOp::HandleCreate\n")); 01182 01183 // Get an empty list of the blob types. 01184 ENSURE(pSelectorTool != NULL, "No selector tool in SelectorInfoBarOp::HandleCreate"); 01185 BlobStyle SelectorBlobs = pSelectorTool->GetBlobStyle(); 01186 if (HasWindow()) 01187 { 01188 // Set all the blob buttons in the info bar according to the information. 01189 SetLongGadgetValue(_R(IDC_SEL_SHOWBOUNDSBLOBS), pSelectorTool->fShowToolBlobs, FALSE); 01190 SetLongGadgetValue(_R(IDC_SEL_SHOWOBJECTBLOBS), SelectorBlobs.Object, FALSE); 01191 SetLongGadgetValue(_R(IDC_SEL_SHOWFILLBLOBS), SelectorBlobs.Fill, FALSE); 01192 // SetLongGadgetValue(_R(IDC_SEL_SHOWARTLINEBLOBS), SelectorBlobs.Artistic, FALSE); 01193 01194 // Set all the option buttons. 01195 SetLongGadgetValue(_R(IDC_SEL_ROTATEBUTTON), fRotateMode, FALSE); 01196 SetLongGadgetValue(_R(IDC_SEL_SCALELINES), fScaleLines, FALSE); 01197 SetLongGadgetValue(_R(IDC_SEL_PADLOCK), fLockAspect, FALSE); 01198 // SetLongGadgetValue(_R(IDC_SEL_LEAVECOPY), fLeaveCopy, FALSE); 01199 // SetLongGadgetValue(_R(IDC_SEL_TRANSFILL), fTransFills, FALSE); 01200 } 01201 01202 // Initialise the edit-field records. 01203 aerEdits[0].nControlID = _R(IDC_SEL_EDIT_X); 01204 aerEdits[1].nControlID = _R(IDC_SEL_EDIT_Y); 01205 aerEdits[2].nControlID = _R(IDC_SEL_EDIT_W); 01206 aerEdits[3].nControlID = _R(IDC_SEL_EDIT_H); 01207 aerEdits[4].nControlID = _R(IDC_SEL_EDIT_XSCALE); 01208 aerEdits[5].nControlID = _R(IDC_SEL_EDIT_YSCALE); 01209 aerEdits[6].nControlID = _R(IDC_SEL_EDIT_ANGLE); 01210 aerEdits[7].nControlID = _R(IDC_SEL_EDIT_SHEAR); 01211 01212 // Now set the edit controls. 01213 SetEdit_OnSelectionChange(); 01214 01215 // Make sure their current values are recorded. 01216 UpdateAllRecords(); 01217 } 01218 01219 01220 01221 /******************************************************************************************** 01222 > BOOL SelectorInfoBarOp::HandleButtonDown(DialogMsg* pDlgMsg) 01223 01224 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> / Rik 01225 Created: 12/7/94 01226 Inputs: A pointer to a "dialogue box" message about a button click. 01227 Returns: TRUE if message handled and should be passd to the InformationBarOp, 01228 FALSE if not handled and should be passed toDialogBarOp (which doesn't 01229 eat messages and can properly invoked operations). 01230 Purpose: For the given button calls the appropriate functions that update the 01231 blob manager. 01232 SeeAlso: SelectorInfoBarOp::Message; SelectorInfoBarOp::UpdateBlobManager 01233 ********************************************************************************************/ 01234 01235 BOOL SelectorInfoBarOp::HandleButtonDown(DialogMsg* pDlgMsg) 01236 { 01237 // Get ourselves an empty blob style (ie all entries set to FALSE) 01238 BlobStyle ChangingBlob; 01239 01240 // Have a look at which button was pressed and deal with it 01241 // switch (pDlgMsg->GadgetID) 01242 01243 // "Show Bounds Blobs" 01244 if (pDlgMsg->GadgetID == _R(IDC_SEL_SHOWBOUNDSBLOBS)) 01245 { 01246 pSelectorTool->BoundsButtonChange(); 01247 } 01248 // "Show Objects". 01249 else if (pDlgMsg->GadgetID == _R(IDC_SEL_SHOWOBJECTBLOBS)) 01250 { // We want to toggle the state of the Object blobs 01251 ChangingBlob.Object = TRUE; 01252 } 01253 // "Show Fills". 01254 else if (pDlgMsg->GadgetID == _R(IDC_SEL_SHOWFILLBLOBS)) 01255 { // We want to toggle the state of the Object blobs 01256 ChangingBlob.Fill = TRUE; 01257 } 01258 else if (pDlgMsg->GadgetID == _R(IDC_SEL_PADLOCK)) 01259 { // Toggle the state of the padlock button. 01260 fLockAspect = !fLockAspect; 01261 } 01262 // "Rotate mode". Will immediately notify the tool, so it can display new blobs. 01263 else if (pDlgMsg->GadgetID == _R(IDC_SEL_ROTATEBUTTON)) 01264 { 01265 pSelectorTool->RotateButtonChange(fRotateMode = !fRotateMode); 01266 } 01267 // "Scale lines when scaling an object". 01268 else if (pDlgMsg->GadgetID == _R(IDC_SEL_SCALELINES)) 01269 { 01270 fScaleLines = !fScaleLines; 01271 01272 // Because the "consider attributes" state (which affects the displayed width/height 01273 // of the selection) can be slaved off this button, we must also ensure that the 01274 // selector tool has cached and is displaying correct info. 01275 if (pSelectorTool) 01276 pSelectorTool->SelectionHasChanged(); 01277 } 01278 // "Flip horizontally". 01279 else if (pDlgMsg->GadgetID == _R(IDC_SEL_FLIPHORZ)) 01280 { 01281 pSelectorTool->FlipButtonChange(FALSE); 01282 } 01283 // "Flip vertically". 01284 else if (pDlgMsg->GadgetID == _R(IDC_SEL_FLIPVERT)) 01285 { 01286 pSelectorTool->FlipButtonChange(TRUE); 01287 } 01288 // "Decrease X a bit". 01289 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_X_LESS)) 01290 { 01291 HandleBumpClickLinear(_R(IDC_SEL_EDIT_X), -1); 01292 } 01293 // "Increase X a bit". 01294 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_X_MORE)) 01295 { 01296 HandleBumpClickLinear(_R(IDC_SEL_EDIT_X), 1); 01297 } 01298 // "Decrease Y a bit". 01299 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_Y_LESS)) 01300 { 01301 HandleBumpClickLinear(_R(IDC_SEL_EDIT_Y), -1); 01302 } 01303 // "Increase Y a bit". 01304 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_Y_MORE)) 01305 { 01306 HandleBumpClickLinear(_R(IDC_SEL_EDIT_Y), 1); 01307 } 01308 // "Decrease W a bit". 01309 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_W_LESS)) 01310 { 01311 HandleBumpClickLinear(_R(IDC_SEL_EDIT_W), -1); 01312 } 01313 // "Increase W a bit". 01314 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_W_MORE)) 01315 { 01316 HandleBumpClickLinear(_R(IDC_SEL_EDIT_W), 1); 01317 } 01318 // "Decrease H a bit". 01319 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_H_LESS)) 01320 { 01321 HandleBumpClickLinear(_R(IDC_SEL_EDIT_H), -1); 01322 } 01323 // "Increase H a bit". 01324 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_H_MORE)) 01325 { 01326 HandleBumpClickLinear(_R(IDC_SEL_EDIT_H), 1); 01327 } 01328 // "Decrease angle a bit". 01329 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_ANGLE_LESS)) 01330 { 01331 HandleBumpClickAngle(_R(IDC_SEL_EDIT_ANGLE), -1, -360.0, +360.0); 01332 } 01333 // "Increase angle a bit". 01334 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_ANGLE_MORE)) 01335 { 01336 HandleBumpClickAngle(_R(IDC_SEL_EDIT_ANGLE), 1, -360.0, +360.0); 01337 } 01338 // "Decrease shear-angle a bit". 01339 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_SHEAR_LESS)) 01340 { 01341 HandleBumpClickAngle(_R(IDC_SEL_EDIT_SHEAR), -1, -89.0, +89.0); 01342 } 01343 // "Increase shear-angle a bit". 01344 else if (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_SHEAR_MORE)) 01345 { 01346 HandleBumpClickAngle(_R(IDC_SEL_EDIT_SHEAR), 1, -89.0, +89.0); 01347 } 01348 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_NW)) 01349 { 01350 pSelectorTool->SetRotateCentre(1); 01351 } 01352 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_N)) 01353 { 01354 pSelectorTool->SetRotateCentre(2); 01355 } 01356 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_NE)) 01357 { 01358 pSelectorTool->SetRotateCentre(3); 01359 } 01360 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_W)) 01361 { 01362 pSelectorTool->SetRotateCentre(4); 01363 } 01364 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_CENTRE)) 01365 { 01366 pSelectorTool->SetRotateCentre(0); 01367 } 01368 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_E)) 01369 { 01370 pSelectorTool->SetRotateCentre(5); 01371 } 01372 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_SW)) 01373 { 01374 pSelectorTool->SetRotateCentre(6); 01375 } 01376 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_S)) 01377 { 01378 pSelectorTool->SetRotateCentre(7); 01379 } 01380 else if (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_SE)) 01381 { 01382 pSelectorTool->SetRotateCentre(8); 01383 } 01384 // Other gadgets, pass to _DialogBarOp_ base class which can properly invoke 01385 // ops attached to gadgets, unlike InformationBarOp which just eats everything. 01386 else 01387 { 01388 // TRACEUSER( "JustinF", _T("SelectorInfoBarOp::HandleButtonDown: passing to DialogBarOp\n")); 01389 return FALSE; 01390 } 01391 01392 // Ask the tool to deal with the blob manager as well as its tool blobs if needed. 01393 if (pSelectorTool != NULL) pSelectorTool->SelectionBlobChange(ChangingBlob); 01394 return TRUE; // handled 01395 01396 } 01397 01398 01399 01400 /******************************************************************************************** 01401 > void SelectorInfoBarOp::HandleButtonUp(DialogMsg* pDlgMsg) 01402 01403 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01404 Created: 1/12/94 01405 Inputs: pDlgMsg pointer to a dialogue message from a button. 01406 Outputs: - 01407 Returns: - 01408 Purpose: For "nudge-buttons", responds to them being released by calling the 01409 HandleEditCommit function, ie. acting as if the user hit the ENTER key 01410 within an edit-field meaning that the program should act on any changes 01411 made. For all other buttons, does nothing. 01412 Errors: - 01413 SeeAlso: - 01414 ********************************************************************************************/ 01415 01416 void SelectorInfoBarOp::HandleButtonUp(DialogMsg* pDlgMsg) 01417 { 01418 if ( 01419 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_X_LESS)) || 01420 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_X_MORE)) || 01421 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_Y_LESS)) || 01422 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_Y_MORE)) || 01423 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_W_LESS)) || 01424 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_W_MORE)) || 01425 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_H_LESS)) || 01426 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_H_MORE)) || 01427 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_ANGLE_LESS)) || 01428 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_ANGLE_MORE)) || 01429 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_SHEAR_LESS)) || 01430 (pDlgMsg->GadgetID == _R(IDC_SEL_BUMP_SHEAR_MORE)) 01431 ) 01432 { 01433 HandleEditCommit(NULL); 01434 } 01435 else if ( 01436 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_NW)) || 01437 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_N) ) || 01438 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_NE)) || 01439 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_W) ) || 01440 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_CENTRE)) || 01441 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_E)) || 01442 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_SW)) || 01443 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_S) ) || 01444 (pDlgMsg->GadgetID == _R(IDC_SEL_GRID_SE)) 01445 ) 01446 { 01447 CGadgetID clicked = pDlgMsg->GadgetID; 01448 clicked = (CGadgetID)0; // Right now remove ALL selected ones to remove toggle functionality. 01449 if (clicked != _R(IDC_SEL_GRID_NW) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_NW), FALSE); 01450 if (clicked != _R(IDC_SEL_GRID_N) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_N), FALSE); 01451 if (clicked != _R(IDC_SEL_GRID_NE) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_NE), FALSE); 01452 if (clicked != _R(IDC_SEL_GRID_W) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_W), FALSE); 01453 if (clicked != _R(IDC_SEL_GRID_CENTRE) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_CENTRE), FALSE); 01454 if (clicked != _R(IDC_SEL_GRID_E) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_E) , FALSE); 01455 if (clicked != _R(IDC_SEL_GRID_SW) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_SW), FALSE); 01456 if (clicked != _R(IDC_SEL_GRID_S) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_S) , FALSE); 01457 if (clicked != _R(IDC_SEL_GRID_SE) ) SetBoolGadgetSelected(_R(IDC_SEL_GRID_SE), FALSE); 01458 } 01459 01460 return; 01461 } 01462 01463 01464 01465 01466 /******************************************************************************************** 01467 > void SelectorInfoBarOp::HandleBumpClickLinear(UINT32 nEditControlID, INT32 nSign) 01468 01469 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01470 Created: 3/11/94 01471 Inputs: nEditControlID --- the identifier of the (EDIT) control associated 01472 with the clicked bump button 01473 nSign --- either -1 or 1, depending on which of the bumps 01474 was clicked (eg. less, more) 01475 Outputs: - 01476 Returns: - 01477 Purpose: Responds to a click on a bump button ("nudge") for a "linear" control, ie. 01478 an X, Y, width or height field, not an angle. The value will be nudged in 01479 the direction indicated by nSign, by the (user preference) nudge distance. 01480 Errors: - 01481 SeeAlso: SelectorInfoBarOp::HandleBumpClickAngle 01482 ********************************************************************************************/ 01483 01484 void SelectorInfoBarOp::HandleBumpClickLinear(UINT32 nEditControlID, INT32 nSign) 01485 { 01486 // If there's no selection then ignore the clicks. 01487 Spread* pUnitSpread = pSelectorTool->GetSelectionSpread(); 01488 if (pUnitSpread == NULL) return; 01489 01490 // Get the dimension units object for the spread containing the selection. 01491 DimScale* pDimScale = DimScale::GetPtrDimScale((Node*) pUnitSpread); 01492 ERROR3IF(pDimScale == NULL, "Null DimScale* in SelectorInfoBarOp::HandleBumpClick"); 01493 01494 // Read the edit field and convert to millipoints. 01495 BOOL fOk; 01496 INT32 nMilli; 01497 String_256 str = GetStringGadgetValue(nEditControlID, &fOk); 01498 if (!fOk || !pDimScale->ConvertToMillipoints( str, &nMilli )) 01499 { 01500 TRACEUSER( "JustinF", _T("Couldn't convert edit control\n") ); 01501 return; 01502 } 01503 01504 // Write the new value to the edit-field. 01505 SetEdit(nEditControlID, nMilli + (nSign * OpNudge::GetNudgeStep()), pUnitSpread, FALSE); 01506 01507 // Set the input focus to the associated edit-field. NB. we don't do this anymore 01508 // because Charles doesn't like it. 01509 // SetKeyboardFocus(nEditControlID); 01510 // HighlightText(nEditControlID); 01511 } 01512 01513 01514 01515 /******************************************************************************************** 01516 > void SelectorInfoBarOp::HandleBumpClickAngle(UINT32 nEditControlID, INT32 nSign, 01517 double Min, double Max) 01518 01519 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01520 Created: 16/11/94 01521 Inputs: nEditControlID identifier of the edit-control 01522 nSign whether to increase (+1) or decrease (-1) the field 01523 Min The minimum allowed value in this field (inclusive) 01524 Max The maximum allowed angle in this field (inclusive) 01525 Outputs: - 01526 Returns: - 01527 Purpose: Responds to a click on a bump button for angles, ie unitless numeric data. 01528 01529 Notes: The value in the icon is incremented by the value in nSign. If this value 01530 is less than the minimum or greater than the maximum, the value will be 01531 clipped to the appropriate limit. 01532 01533 Errors: - 01534 SeeAlso: - 01535 ********************************************************************************************/ 01536 01537 void SelectorInfoBarOp::HandleBumpClickAngle(UINT32 nEditControlID, INT32 nSign, double Min, double Max) 01538 { 01539 // If there's nothing selected then ignore the clicks. 01540 if (pSelectorTool->GetSelectionSpread() == NULL) return; 01541 01542 // Try to read the edit-field. 01543 BOOL fOk; 01544 String_256 str = GetStringGadgetValue(nEditControlID, &fOk); 01545 if (!fOk) 01546 { 01547 TRACEUSER( "JustinF", _T("Couldn't read edit control\n") ); 01548 return; 01549 } 01550 01551 // Convert from text to a number. 01552 double nAngle = Convert::StringToDouble( str, MILLIPOINTS, &fOk); 01553 if (!fOk) 01554 { 01555 TRACEUSER( "JustinF", _T("Couldn't convert edit control\n") ); 01556 return; 01557 } 01558 01559 // Increment as required 01560 nAngle += nSign; 01561 01562 // And clip to allowable range 01563 if (nAngle < Min) 01564 nAngle = Min; 01565 01566 if (nAngle > Max) 01567 nAngle = Max; 01568 01569 // Adjust it by nSign and write the new value to the edit-field. 01570 SetEdit(nEditControlID, (ANGLE) nAngle, NULL, FALSE); 01571 01572 // Set the input focus to the associated edit-field. NB. we don't do this anymore 01573 // because Charles doesn't like it. 01574 // SetKeyboardFocus(nEditControlID); 01575 // HighlightText(nEditControlID); 01576 } 01577 01578 01579 01580 /******************************************************************************************** 01581 > void SelectorInfoBarOp::HandleEditCommit(DialogMsg* pDlgMsg) 01582 01583 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01584 Created: 31/8/94 01585 Inputs: pDlgMsg the "commit" dialogue message sent when the user hits ENTER 01586 within an edit-field. 01587 Outputs: - 01588 Returns: - 01589 Purpose: Reads the text from the edit-fields, converts it to millipoints, informs the 01590 selector tool that the user has changed the selection's position and/or 01591 extent. 01592 Errors: - 01593 SeeAlso: - 01594 ********************************************************************************************/ 01595 01596 void SelectorInfoBarOp::HandleEditCommit(DialogMsg* pDlgMsg) 01597 { 01598 // If there's nothing selected then ignore the clicks. 01599 if (pSelectorTool->GetSelectionSpread() == NULL) return; 01600 01601 // Ignore all but "hard-commits" in proper dialogue messages (not "faked" ones). 01602 if (pDlgMsg != NULL && ((SelChangeMsgSubType) pDlgMsg->DlgMsgParam) != ENTER_COMMIT) 01603 return; 01604 01605 01606 // Tell the selector tool to ignore selection change messages until further notice. 01607 pSelectorTool->fIgnoreSelChange = TRUE; 01608 01609 // Compare the current contents of the edit-fields against their recorded values, to 01610 // see if any have been modified. 01611 BOOL fMustTransform = FALSE; 01612 for (INT32 i = 0; i < 8; i++) 01613 { 01614 if (HasChangedRecord(i)) 01615 { 01616 UpdateRecord(&aerEdits[i]); 01617 fMustTransform = TRUE; 01618 } 01619 } 01620 01621 // After checking and updating our records, do we have to run a transform? Note that 01622 // we check these as they appear on the bar from left to right. 01623 UINT32 nErrorMsg=0; 01624 fConvertedOK = TRUE; 01625 01626 if (fMustTransform) 01627 { 01628 01629 TRACEUSER( "Matt", _T("HandleEditCommit()\n")); 01630 Range* Selection = GetApplication()->FindSelection(); 01631 RangeControl TransFlags = Selection->GetRangeControlFlags(); 01632 TransFlags.IgnoreNoneRenderable=TRUE; 01633 TransFlags.IgnoreInvisibleLayers = TRUE; 01634 Selection->SetRangeControl(TransFlags); 01635 SliceHelper::ModifySelectionToContainWholeButtonElements(); 01636 01637 01638 if (aerEdits[0].fIsDirty || aerEdits[1].fIsDirty) 01639 { 01640 // X or Y has been changed - run a translate. 01641 INT32 x = ConvertMillipointRecord(0); 01642 INT32 y = ConvertMillipointRecord(1); 01643 01644 // Convert the entered pages coordinates to spread-relative coordinates. 01645 Spread* pSpread = pSelectorTool->GetSelectionSpread(); 01646 ERROR3IF(pSpread == NULL,"No selected Spread* in SelectorInfoBarOp::HandleEditCommit"); 01647 DocCoord dc = UserCoord(x,y).ToSpread(pSpread); 01648 01649 if (!fConvertedOK) 01650 { 01651 nErrorMsg = _R(IDS_SEL_ERROR_XY); 01652 goto AfterXform; 01653 } 01654 01655 pSelectorTool->DoTranslateImmediate(dc.x, dc.y); 01656 } 01657 01658 if (aerEdits[2].fIsDirty || aerEdits[3].fIsDirty) 01659 { 01660 // W or H has been changed - run a scale. 01661 INT32 w = ConvertMillipointRecord(2); 01662 INT32 h = ConvertMillipointRecord(3); 01663 if (!fConvertedOK || w == 0 || h == 0) 01664 { 01665 fConvertedOK = FALSE; 01666 nErrorMsg = _R(IDS_SEL_ERROR_WH); 01667 goto AfterXform; 01668 } 01669 01670 if (fLockAspect) 01671 { 01672 // The aspect ratio is locked, which means we must scale either the width or 01673 // height accordingly, whichever was not changed. If both were changed then 01674 // we have a little problem. 01675 DocRect oldrect = pSelectorTool->GetSelectionBounds(DontConsiderAttrs()); 01676 if (!aerEdits[2].fIsDirty) 01677 { 01678 w = MulDiv32By32(oldrect.Width(), h, oldrect.Height()); 01679 } 01680 else 01681 { 01682 h = MulDiv32By32(w, oldrect.Height(), oldrect.Width()); 01683 } 01684 } 01685 01687 // if( !DontConsiderAttrs() && SelectorTool::fUseScalingFix ) 01688 // pSelectorTool->DoScaleImmediate(w, h, TRUE ); // special fix 01689 // else 01690 pSelectorTool->DoScaleImmediate(w, h); // normal 01691 } 01692 01693 if (aerEdits[4].fIsDirty || aerEdits[5].fIsDirty) 01694 { 01695 // X-scale or Y-scale has been changed - run a scale. 01696 double w = ConvertRecord(4); 01697 double h = ConvertRecord(5); 01698 01699 // Ensure that the entered value is valid. Note that values near to zero are 01700 // actually illegal (they'd cause a divide by zero), but these are properly handled 01701 // by DoScalePercentImmediate, below. 01702 if (!fConvertedOK) 01703 { 01704 fConvertedOK = FALSE; 01705 nErrorMsg = _R(IDS_SEL_ERROR_XYSCALE); 01706 goto AfterXform; 01707 } 01708 01709 // Quietly limit the maximum scaling to 200 times (20,000%). This should allow more 01710 // than enough scaling, especially while our zoom limits are 26000% 01711 if (w > 19999.0) w = 19999.0; 01712 if (w < -19999.0) w = -19999.0; 01713 if (h > 19999.0) h = 19999.0; 01714 if (h < -19999.0) h = -19999.0; 01715 01716 // Check for the "Lock Aspect" button. 01717 if (fLockAspect) 01718 { 01719 // If only one edit has been changed then set the other to be equal. 01720 if (!aerEdits[4].fIsDirty) 01721 { 01722 w = h; 01723 SetDoubleEdit(_R(IDC_SEL_EDIT_XSCALE), w, FALSE); 01724 } 01725 else 01726 { 01727 // One or both have been changed but "lock aspect" is set, which presents a 01728 // problem. For now take the x-scale as overriding. 01729 h = w; 01730 SetDoubleEdit(_R(IDC_SEL_EDIT_YSCALE), h, FALSE); 01731 } 01732 } 01733 01734 pSelectorTool->DoScalePercentImmediate(w, h); 01735 } 01736 01737 if (aerEdits[6].fIsDirty) 01738 { 01739 // Angle has been changed - run a rotate. 01740 double Angle = ConvertRecord(6); 01741 if (!fConvertedOK) 01742 { 01743 nErrorMsg = _R(IDS_SEL_ERROR_ANGLE); 01744 goto AfterXform; 01745 } 01746 01747 // Ensure the angle is between -360 and +360. We use an integer modulus to get 01748 // the angle back under control. 01749 if (fabs(Angle) >= 360.0) 01750 { 01751 // The angle is out of range, so we need to make it sensible 01752 BOOL Negative = (Angle < 0.0); 01753 01754 Angle = ((INT32)floor(fabs(Angle))) % 360; 01755 01756 if (Negative) 01757 Angle = -Angle; 01758 } 01759 01760 pSelectorTool->DoRotateImmediate((FIXED16) Angle); 01761 } 01762 01763 if (aerEdits[7].fIsDirty) 01764 { 01765 // Shear-angle has been changed - run a shear. 01766 double Angle = ConvertRecord(7); 01767 if (!fConvertedOK) 01768 { 01769 nErrorMsg = _R(IDS_SEL_ERROR_SHEAR); 01770 goto AfterXform; 01771 } 01772 01773 // Clip the angle to lie between +/- 89.0 degrees 01774 if (fabs(Angle) > 89.0) 01775 Angle = (Angle < 0.0) ? -89.0 : 89.0; 01776 01777 pSelectorTool->DoShearImmediate((FIXED16) Angle); 01778 } 01779 01780 SliceHelper::RestoreSelection(); 01781 } 01782 01783 AfterXform: 01784 // Check if we got here because an edit conversion failed. 01785 if (!fConvertedOK) ReportEditError(nErrorMsg); 01786 01787 // Reset the selection-change handler flag. If we ran a transform then manually 01788 // update the selection. 01789 pSelectorTool->fIgnoreSelChange = FALSE; 01790 01791 if (fMustTransform && fConvertedOK) 01792 { 01793 pSelectorTool->SelectionHasChanged(); 01794 } 01795 } 01796 01797 01798 01799 01800 /******************************************************************************************** 01801 > void SelectorInfoBarOp::ReportEditError(UINT32 nErrorMsgID) 01802 01803 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01804 Created: 24/2/95 01805 Inputs: nErrorMsgID the string resource ID of the error message to 01806 display in the error dialogue. 01807 Outputs: - 01808 Returns: - 01809 Purpose: Reports errors the user makes when typing in the selector tool-bar 01810 edit fields. 01811 Errors: - 01812 SeeAlso: SelectorInfoBarOp::HandleEditCommit 01813 ********************************************************************************************/ 01814 01815 void SelectorInfoBarOp::ReportEditError(UINT32 nErrorMsgID) 01816 { 01817 // Report the error with a message box. 01818 ToolInformError(TOOLID_SELECTOR, nErrorMsgID); 01819 01820 // Reset the edit fields to correct values. 01821 SetEdit_OnSelectionChange(); 01822 } 01823 01824 01825 01826 /******************************************************************************************** 01827 > void SelectorInfoBarOp::HandleGridButton(DialogMsg* pDlgMsg) 01828 01829 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01830 Created: 16/11/94 01831 Inputs: pDlgMsg pointer to a dialogue message. 01832 Outputs: - 01833 Returns: - 01834 Purpose: Responds to a click on the "telephone keypad", passing the event on to 01835 the selector tool. 01836 Errors: - 01837 SeeAlso: SelectorTool::SetRotateCentre 01838 ********************************************************************************************/ 01839 01840 void SelectorInfoBarOp::HandleGridButton(DialogMsg* pDlgMsg) 01841 { 01842 pSelectorTool->SetRotateCentre((INT32) pDlgMsg->DlgMsgParam); 01843 } 01844 01845 01846 01847 /******************************************************************************************** 01848 > virtual DialogBarOp* SelectorInfoBarOpCreate::Create() 01849 01850 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01851 Created: 11/7/94 01852 Inputs: - 01853 Outputs: - 01854 Returns: A pointer to a SelectorBarOp object allocated on the heap. 01855 Purpose: Used by the bar code to create an appropriate InformationBarOp. 01856 Errors: - 01857 SeeAlso: class SelectorInfoBarOp; class BarCreate 01858 ********************************************************************************************/ 01859 01860 DialogBarOp* SelectorInfoBarOpCreate::Create() 01861 { 01862 return new SelectorInfoBarOp; 01863 }