00001 // $Id: cartctl.cpp 1410 2006-07-05 17:45:12Z 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 00099 00100 #include "camtypes.h" 00101 00102 #include "cartctl.h" 00103 #include "cartprov.h" 00104 #include "dlgevt.h" 00105 00106 /***************************************************************************** 00107 00108 This file contains the class for wxCamArtControl, derived from 00109 wxEvtHandler. This contains a mapping allowing dialogs of ANY class 00110 derived from wxDialog to call the relevant bits of DialogManager. 00111 00112 *****************************************************************************/ 00113 00114 DEFINE_EVENT_TYPE(wxEVT_CAMARTCONTROL_INVOKE) 00115 IMPLEMENT_DYNAMIC_CLASS( wxCamArtControlEvent, wxEvent ) 00116 00117 IMPLEMENT_DYNAMIC_CLASS( wxCamArtControl, wxControl ) 00118 BEGIN_EVENT_TABLE(wxCamArtControl, wxControl) 00119 EVT_CAMARTCONTROL_INVOKE(wxID_ANY, wxCamArtControl::OnInvoke) 00120 EVT_PAINT(wxCamArtControl::OnPaint) 00121 EVT_MOUSE_EVENTS(wxCamArtControl::OnMouseEvent) 00122 EVT_TIMER(_R(IDC_WXCAMARTCONTROL_AUTOREPEAT), wxCamArtControl::OnTimer) 00123 END_EVENT_TABLE(); 00124 00125 IMPLEMENT_DYNAMIC_CLASS( wxCamArtControlXmlHandler, wxXmlResourceHandler) 00126 00127 /******************************************************************************************** 00128 00129 > BOOL wxCamArtControl::Create( wxWindow * parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, 00130 [TYPENOTE: Correct] long style, const wxValidator& validator = wxDefaultValidator, 00131 wxCamArtControlStyle cacstyle = (wxCamArtControlStyle)0, 00132 wxString opdesc = wxString(_T(""))) 00133 00134 Author: Alex_Bligh <alex@alex.org.uk> 00135 Created: 30/12/2005 00136 Inputs: parent - parent window 00137 id - id to use 00138 pos - position 00139 size - size 00140 style - style 00141 validator - validator (up to here, all the same as wxControl) 00142 cacstyle - the style of CamArtControl to use, i.e. the flags passed 00143 opdesc - the opdescriptor to use, OR the empty string 00144 Outputs: None 00145 Returns: TRUE if succeeded, FALSE if fails 00146 Purpose: Initialize the control 00147 Errors: via wxMessageBox 00148 SeeAlso: - 00149 00150 ********************************************************************************************/ 00151 00152 BOOL wxCamArtControl::Create( wxWindow * parent, wxWindowID id, const wxPoint& pos, const wxSize& size, 00153 /*TYPENOTE: Correct*/ long style, const wxValidator& validator, 00154 wxCamArtControlStyle cacstyle, 00155 wxString opdesc) 00156 { 00157 if (!wxControl::Create(parent, id, pos, size, style, validator)) 00158 return FALSE; 00159 00160 // Complete bodge to default to small button bars but large toolbars 00161 if (!(cacstyle & wxCACS_TOOLBACKGROUND)) 00162 cacstyle = (wxCamArtControlStyle)(cacstyle | CAF_SMALL); 00163 00164 m_CamArtControlStyle = cacstyle; 00165 m_OpDesc = opdesc; 00166 FindBitmap(); 00167 return TRUE; 00168 } 00169 00170 /******************************************************************************************** 00171 00172 > wxSize wxCamArtControl::DoGetBestSize() const 00173 00174 00175 Author: Alex_Bligh <alex@alex.org.uk> 00176 Created: 30/12/2005 00177 Inputs: None 00178 Outputs: None 00179 Returns: The best size for the control 00180 Purpose: Initialize resources 00181 Errors: via wxMessageBox 00182 SeeAlso: - 00183 00184 ********************************************************************************************/ 00185 00186 wxSize wxCamArtControl::DoGetBestSize() const 00187 { 00188 ((wxCamArtControl *)this)->FindBitmap(); 00189 00190 wxSize ret = m_BestSize; // ret( wxControl::DoGetBestSize() ); 00191 00192 if ((GetStyle() & wxCACS_TEXT) && (!(GetStyle() & wxCACS_EXACTFIT))) 00193 { 00194 wxSize DefaultSize; 00195 DefaultSize=wxButton::GetDefaultSize(); 00196 if (GetStyle() & wxCACS_HALFHEIGHT) 00197 DefaultSize.y = (DefaultSize.y/2)-2; 00198 if (ret.x < DefaultSize.x) ret.x = DefaultSize.x; 00199 if (ret.y < DefaultSize.y) ret.y = DefaultSize.y; 00200 } 00201 00202 CacheBestSize(ret); 00203 return ret; 00204 } 00205 00206 /******************************************************************************************** 00207 00208 > void wxCamArtControl::FindBitmap() 00209 00210 00211 Author: Alex_Bligh <alex@alex.org.uk> 00212 Created: 30/12/2005 00213 Inputs: None 00214 Outputs: None 00215 Returns: None 00216 Purpose: Find the bitmap associated with the control, and set our cached size 00217 Errors: - 00218 SeeAlso: - 00219 00220 ********************************************************************************************/ 00221 00222 void wxCamArtControl::FindBitmap() 00223 { 00224 m_BestSize=(CamArtProvider::Get())->GetSize(GetBitmapId(), GetArtFlags(), GetLabel()); 00225 return; 00226 } 00227 00228 /******************************************************************************************** 00229 00230 > void wxCamArtControl::OnPaint(wxPaintEvent & event) 00231 00232 00233 Author: Alex_Bligh <alex@alex.org.uk> 00234 Created: 30/12/2005 00235 Inputs: event - the event 00236 Outputs: - 00237 Returns: - 00238 Purpose: Paints the control 00239 Errors: - 00240 SeeAlso: - 00241 00242 ********************************************************************************************/ 00243 00244 void wxCamArtControl::OnPaint(wxPaintEvent & event) 00245 { 00246 wxPaintDC dc(this); 00247 00248 wxRect rect = GetClientRect(); 00249 CamArtProvider::Get()->Draw(dc, rect, GetBitmapId(), GetArtFlags(), GetLabel()); 00250 } 00251 00252 00253 /******************************************************************************************** 00254 00255 > void wxCamArtControl::OnMouseEvent(wxMouseEvent & event) 00256 00257 00258 Author: Alex_Bligh <alex@alex.org.uk> 00259 Created: 30/12/2005 00260 Inputs: event - the event 00261 Outputs: - 00262 Returns: - 00263 Purpose: Handles mouse events 00264 Errors: - 00265 SeeAlso: - 00266 00267 ********************************************************************************************/ 00268 00269 void wxCamArtControl::OnMouseEvent(wxMouseEvent & event) 00270 { 00271 CamArtFlags OldState = m_State; 00272 BOOL ButtonClick=FALSE; 00273 00274 if ((m_CamArtControlStyle & wxCACS_PUSHBUTTON) && IsEnabled()) 00275 { 00276 if (event.LeftDown() || event.LeftDClick()) 00277 { 00278 if (m_CamArtControlStyle & wxCACS_TOGGLEBUTTON) 00279 m_State = (CamArtFlags)(m_State ^ CAF_SELECTED); 00280 else 00281 m_State = (CamArtFlags)(m_State | CAF_SELECTED); 00282 ButtonClick=TRUE; 00283 } 00284 else if (event.LeftUp()) 00285 { 00286 if (!(m_CamArtControlStyle & wxCACS_TOGGLEBUTTON)) 00287 m_State = (CamArtFlags)(m_State & ~CAF_SELECTED); 00288 m_Timer.Stop(); 00289 } 00290 else if (event.Leaving()) 00291 { 00292 if (!(m_CamArtControlStyle & wxCACS_TOGGLEBUTTON)) 00293 m_State = (CamArtFlags)(m_State & ~CAF_SELECTED); 00294 m_State = (CamArtFlags)(m_State & ~CAF_BUTTONHOVER); 00295 m_Timer.Stop(); 00296 } 00297 else if (event.Entering()) 00298 { 00299 if (m_CamArtControlStyle & wxCACS_ALLOWHOVER) 00300 m_State = (CamArtFlags)(m_State | CAF_BUTTONHOVER); 00301 } 00302 m_Value=(m_State & CAF_SELECTED)?1:0; 00303 } 00304 00305 // Irritatingly wxMouseEvent does not propagate to the parent, but we expect it to. 00306 // so we have to fake it (sigh) 00307 // event.Skip(); // pretend we did not handle it, so it falls through to the dialog 00308 00309 if ( !(GetExtraStyle() & wxWS_EX_BLOCK_EVENTS) ) 00310 { 00311 wxWindow * pParent = GetParent(); 00312 if (pParent && !pParent->IsBeingDeleted()) 00313 { 00314 wxEvtHandler *pHandler = pParent->GetEventHandler(); 00315 if (pHandler && pHandler->IsKindOf(CLASSINFO(DialogEventHandler))) // Only propagate to our own dialogs 00316 { 00317 pHandler->ProcessEvent(event); 00318 } 00319 } 00320 } 00321 00322 if (m_State != OldState) 00323 { 00324 Refresh(); 00325 } 00326 00327 if (ButtonClick) 00328 { 00329 Invoke(); 00330 if (IsEnabled() && !(m_CamArtControlStyle & wxCACS_TOGGLEBUTTON) && !(m_CamArtControlStyle & wxCACS_NOAUTOREPEAT)) // Toggle buttons don't autorepeat 00331 { 00332 // We start the timer at the end, as the Op may be an INT32 one 00333 m_AREventPending = FALSE; // Just in case an event got lost in flight 00334 m_Timer.Start(m_ARDelay, TRUE); 00335 } 00336 } 00337 } 00338 00339 /******************************************************************************************** 00340 00341 > void wxCamArtControl::OnTimer(wxTimerEvent & event) 00342 00343 00344 Author: Alex_Bligh <alex@alex.org.uk> 00345 Created: 30/12/2005 00346 Inputs: event - the event 00347 Outputs: - 00348 Returns: - 00349 Purpose: Handles autorepeat timer events 00350 Errors: - 00351 SeeAlso: - 00352 00353 We do not process these immediately because otherwise the application does not have a chance 00354 to redraw between undo etc. Instead we send a deferred message back to ourselves 00355 00356 ********************************************************************************************/ 00357 00358 void wxCamArtControl::OnTimer(wxTimerEvent & event) 00359 { 00360 m_Timer.Stop(); 00361 00362 if (!IsEnabled()) 00363 return; // Don't even send messages if the control is greyed 00364 00365 // Sadly, what can happen is that the Op can set in place a redraw, and during the redraw 00366 // the button will left. But our timer gets her first. So we have to check whether the 00367 // button is still down 00368 if (!::wxGetMouseState().LeftDown()) 00369 return; 00370 00371 if (!m_AREventPending) // don't process if another event was pending 00372 { 00373 m_AREventPending = TRUE; 00374 wxCamArtControlEvent evt(wxEVT_CAMARTCONTROL_INVOKE, GetId()); 00375 GetEventHandler()->AddPendingEvent(evt); // Send it off deferred 00376 } 00377 00378 m_Timer.Start(m_ARRepeat, FALSE); 00379 } 00380 00381 /******************************************************************************************** 00382 00383 > void wxCamArtControl::OnInvoke(wxCamArtControlEvent & event) 00384 00385 00386 Author: Alex_Bligh <alex@alex.org.uk> 00387 Created: 30/12/2005 00388 Inputs: event - the event 00389 Outputs: - 00390 Returns: - 00391 Purpose: Handles deferred invoke events 00392 Errors: - 00393 SeeAlso: - 00394 00395 We do not process these immediately because otherwise the application does not have a chance 00396 to redraw between undo etc. Instead we send a deferred message back to ourselves 00397 00398 ********************************************************************************************/ 00399 00400 void wxCamArtControl::OnInvoke(wxCamArtControlEvent & event) 00401 { 00402 m_AREventPending = FALSE; 00403 if (!::wxGetMouseState().LeftDown()) 00404 { 00405 m_Timer.Stop(); 00406 return; 00407 } 00408 Invoke(); 00409 } 00410 00411 /******************************************************************************************** 00412 00413 > void wxCamArtControl::Invoke() 00414 00415 00416 Author: Alex_Bligh <alex@alex.org.uk> 00417 Created: 30/12/2005 00418 Inputs: - 00419 Outputs: - 00420 Returns: - 00421 Purpose: Does the work of the button being pressed 00422 Errors: - 00423 SeeAlso: - 00424 00425 We send ourselves our COMMAND event (which DialogManager picks up) and invoke the op 00426 descriptor attached ourselves. 00427 00428 ********************************************************************************************/ 00429 00430 void wxCamArtControl::Invoke() 00431 { 00432 if (!IsEnabled()) 00433 { 00434 m_Timer.Stop(); 00435 return; // Don't even send messages if the control is greyed 00436 } 00437 00438 wxCommandEvent ButtonEvent(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); 00439 ProcessEvent(ButtonEvent); 00440 // If it's attached to an OpDescriptor, we invoke it. 00441 // ControlList::/*Get*/()->Invoke(this); 00442 } 00443 00444 /******************************************************************************************** 00445 00446 > wxCamArtControlXmlHandler::wxCamArtControlXmlHandler() 00447 00448 00449 Author: Alex_Bligh <alex@alex.org.uk> 00450 Created: 30/12/2005 00451 Inputs: - 00452 Outputs: - 00453 Returns: - 00454 Purpose: Constructor 00455 Errors: - 00456 SeeAlso: - 00457 00458 ********************************************************************************************/ 00459 00460 wxCamArtControlXmlHandler::wxCamArtControlXmlHandler() : wxXmlResourceHandler() 00461 { 00462 XRC_ADD_STYLE(wxCACS_TEXT); 00463 XRC_ADD_STYLE(wxCACS_TOOLBACKGROUND); 00464 XRC_ADD_STYLE(wxCACS_PUSHBUTTON); 00465 XRC_ADD_STYLE(wxCACS_TOGGLEBUTTON); 00466 XRC_ADD_STYLE(wxCACS_ALWAYS3D); 00467 XRC_ADD_STYLE(wxCACS_ALLOWHOVER); 00468 XRC_ADD_STYLE(wxCACS_NOINTERNALBORDER); 00469 XRC_ADD_STYLE(wxCACS_HALFHEIGHT); 00470 XRC_ADD_STYLE(wxCACS_EXACTFIT); 00471 XRC_ADD_STYLE(wxCACS_TOP); 00472 XRC_ADD_STYLE(wxCACS_BOTTOM); 00473 XRC_ADD_STYLE(wxCACS_LEFT); 00474 XRC_ADD_STYLE(wxCACS_RIGHT); 00475 XRC_ADD_STYLE(wxCACS_NOAUTOREPEAT); 00476 XRC_ADD_STYLE(wxCACS_STATUSBARTEXT); 00477 AddWindowStyles(); 00478 } 00479 00480 /******************************************************************************************** 00481 00482 > wxObject * wxCamArtControlXmlHandler::DoCreateResource() 00483 00484 00485 Author: Alex_Bligh <alex@alex.org.uk> 00486 Created: 30/12/2005 00487 Inputs: - 00488 Outputs: - 00489 Returns: - 00490 Purpose: Creates a wxCamArtControl from XML 00491 Errors: - 00492 SeeAlso: - 00493 00494 ********************************************************************************************/ 00495 00496 wxObject * wxCamArtControlXmlHandler::DoCreateResource() 00497 { 00498 XRC_MAKE_INSTANCE(control, wxCamArtControl); 00499 control->Create(m_parentAsWindow, 00500 GetID(), 00501 GetPosition(), 00502 GetSize(), 00503 (GetStyle() & ~wxBORDER_MASK) | wxNO_BORDER, 00504 wxDefaultValidator, 00505 (wxCamArtControlStyle)GetStyle(_T("camartstyle")), 00506 GetParamValue(_T("optoken")) 00507 ); 00508 00509 SetupWindow(control); 00510 00511 return control; 00512 } 00513 00514 /******************************************************************************************** 00515 00516 > bool [TYPENOTE: Correct] wxCamArtControlXmlHandler::DoCreateResource() 00517 00518 00519 Author: Alex_Bligh <alex@alex.org.uk> 00520 Created: 30/12/2005 00521 Inputs: node - a pointer to the xml node 00522 Outputs: - 00523 Returns: TRUE if we can load it 00524 Purpose: Determines whether or not we can handle an object type 00525 Errors: - 00526 SeeAlso: - 00527 00528 ********************************************************************************************/ 00529 00530 bool /*TYPENOTE: Correct*/ wxCamArtControlXmlHandler::CanHandle(wxXmlNode *node) 00531 { 00532 bool fOurClass = node->GetPropVal(wxT("class"), wxEmptyString) == wxT("wxCamArtControl"); 00533 return fOurClass; 00534 00535 // This doesn't work on some compilers (although it is identical to what's above 00536 // just not in a function implemented in a header) 00537 // return (IsOfClass(node, wxT("wxCamArtControl"))); 00538 }