[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]

[XaraXtreme-commits] Commit Complete



Commit by  : phil
Repository : xara
Revision   : 1395
Date       : Fri Jun 30 18:00:03 BST 2006

Changed paths:
   M /Trunk/XaraLX/Kernel/rulers.cpp
   M /Trunk/XaraLX/Kernel/rulers.h
   M /Trunk/XaraLX/Kernel/tool.cpp
   M /Trunk/XaraLX/Kernel/tool.h
   M /Trunk/XaraLX/wxOil/oilruler.cpp
   M /Trunk/XaraLX/wxOil/oilruler.h
   M /Trunk/XaraLX/wxOil/wincoord.cpp
   M /Trunk/XaraLX/wxOil/wincoord.h

New framework to allow the current Tool to handle clicks on Rulers.
Ruler rendering also gives the current Tool the chance to modify the displayed origin position.


Diff:
Index: Trunk/XaraLX/Kernel/tool.h
===================================================================
--- Trunk/XaraLX/Kernel/tool.h	(revision 1394)
+++ Trunk/XaraLX/Kernel/tool.h	(revision 1395)
@@ -116,6 +116,7 @@
 class ToolListItem;
 class Spread;
 class KeyPress;
+class RulerBase;
 
 // Everyone tool needs a valid Tool ID. They get allocated here. Camelot
 // tools written by us should have an ID in the range 2 - 49. The range
@@ -358,6 +359,17 @@
 	// Allow the selection and deselection of a tool
 	virtual void SelectChange(BOOL IsSelected);
 
+	// Allow the Current Tool to modify coordinates displayed on the Ruler
+	virtual void GetRulerCoord(const DocRect, UserRect*);
+
+	// Allow the Current Tool to handle Ruler clicks
+	virtual BOOL OnRulerClick( DocCoord PointerPos,
+							   ClickType Click,
+							   ClickModifiers Mods,
+							   Spread* pSpread,
+							   RulerBase* pRuler
+							 );
+
 	// Easy access to the tool's info structure
 	ToolListItem *Parent;
 
Index: Trunk/XaraLX/Kernel/rulers.h
===================================================================
--- Trunk/XaraLX/Kernel/rulers.h	(revision 1394)
+++ Trunk/XaraLX/Kernel/rulers.h	(revision 1395)
@@ -137,6 +137,8 @@
 
 	BOOL Redraw(OilRect* pOilRect);
 
+	virtual BOOL OnRulerClick(OilCoord, ClickType, ClickModifiers);
+
 protected:
 	RulerPair* pRulerPair;
 	OILRuler*  pOILRuler;
Index: Trunk/XaraLX/Kernel/rulers.cpp
===================================================================
--- Trunk/XaraLX/Kernel/rulers.cpp	(revision 1394)
+++ Trunk/XaraLX/Kernel/rulers.cpp	(revision 1395)
@@ -117,6 +117,7 @@
 #include "grid.h"
 #include "appprefs.h"
 #include "layerprp.h"
+#include "camelot.h"
 
 DECLARE_SOURCE("$Revision$");
 
@@ -175,7 +176,12 @@
 		return TRUE;
 
 	// Convert the OilRect to a UserRect and limit to spread's paste board
-	UserRect UpdateRect = pUpdateOilRect->ToDoc(pSpread,pDocView).ToSpread(pSpread,pDocView).ToUser(pSpread);
+	DocRect drect = pUpdateOilRect->ToDoc(pSpread,pDocView).ToSpread(pSpread,pDocView);
+	UserRect UpdateRect = drect.ToUser(pSpread);
+
+	// Give the current tool the chance to modify the UserCoord displayed by the ruler
+	Tool::GetCurrent()->GetRulerCoord(drect, &UpdateRect);
+
 	MILLIPOINT LoLimit = GetOrd(pRD->PasteBoardUserRect.lo);
 	MILLIPOINT HiLimit = GetOrd(pRD->PasteBoardUserRect.hi);
 	if (GetOrd(UpdateRect.lo)<LoLimit) UpdateRect.lo=MakeCoord(LoLimit);
@@ -239,6 +245,68 @@
 }
 
 
+/********************************************************************************************
+
+> 	BOOL RulerBase::OnRulerClick(OilCoord PointerPos, ClickType Click, ClickModifiers Mods)
+
+    Author: 	Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+    Created:	30/Jun/2006
+	Inputs:		PointerPos - Position of click from OS
+				Click - Type of click (single, double or drag)
+				Mods - Other inputs which modify the meaning of the click
+    Purpose:    Convert click coordinates into DocCoords and pass them on to the current
+			    tool.
+                   			                                     
+********************************************************************************************/
+/*	Technical notes:
+				This routine also converts the click position into WorkCoords and keeps it
+				for those routines which need it. They can get it by calling
+				GetClickWorkCoord so long as the ViewState hasn't changed in the meantime.
+
+********************************************************************************************/
+
+BOOL RulerBase::OnRulerClick(OilCoord PointerPos, ClickType Click, ClickModifiers Mods)
+{
+	ERROR3IF(pRulerPair==NULL, "pRulerPair unexpectedly NULL");
+	ERROR3IF(pRulerPair->GetpSpread()==NULL, "pRulerPair->pSpread unexpectedly NULL");
+	ERROR3IF(pRulerPair->GetpDocView()==NULL, "pRulerPair->pDocView unexpectedly NULL");
+
+	// Ignore if system is disabled
+	if (CCamApp::IsDisabled())
+		return FALSE;						     	// If the system is disabled, ignore
+
+	// grab the focus if it's stuck in  a control somewhere
+//	DialogManager::DefaultKeyboardFocus();	
+	
+	// Find the spread in which the click happened
+	Spread *pSpread = pRulerPair->GetpSpread();
+
+	if (pSpread == NULL)
+	{
+		ERROR3("Could not find Ruler pair spread");
+		return FALSE; // Exit reasonably nicely
+	}
+
+	// When the user clicks on a spread which is not the selected spread then this spread becomes
+	// selected and the selection is cleared.
+	// NOPE! Since this click occurred on a Ruler, not on the page, the Tool::OnRulerClick handler
+	// must make the choice about setting the selected spread IFF it handles the click
+//	Document::SetSelectedViewAndSpread(pDoc, this, pSpread);
+
+	// First of all convert the OilRect into device coords
+	DocCoord DocPos = PointerPos.ToDoc( pSpread, pRulerPair->GetpDocView() );
+	
+	// Convert the coord to spread coords
+	pSpread->DocCoordToSpreadCoord(&DocPos);
+
+	if (Tool::GetCurrent())
+		return Tool::GetCurrent()->OnRulerClick(DocPos, Click, Mods, pSpread, this);
+
+	return FALSE;
+}
+
+
+
 //////////////////////////////////////////////////////////////////////////////
 // HorizontalRuler class
 
@@ -435,6 +503,9 @@
 	pSpread->DocCoordToSpreadCoord(&PasteSpreadRect);
 	UserRect PasteBoardUserRect = PasteSpreadRect.ToUser(pSpread);
 
+	// Give the current tool the chance to modify the UserCoord displayed by the ruler
+	Tool::GetCurrent()->GetRulerCoord(PasteSpreadRect, &PasteBoardUserRect);
+
 	// hence the start and end values in terms of ruler units
 	double XStart = fabs(PasteBoardUserRect.lo.x/GratStepSize)*GratStep;
 	double XEnd   = fabs(PasteBoardUserRect.hi.x/GratStepSize)*GratStep;
Index: Trunk/XaraLX/Kernel/tool.cpp
===================================================================
--- Trunk/XaraLX/Kernel/tool.cpp	(revision 1394)
+++ Trunk/XaraLX/Kernel/tool.cpp	(revision 1395)
@@ -1523,11 +1523,67 @@
 	// Override me!
 }
 
+/********************************************************************************************
 
+>	virtual void Tool_v1::GetRulerCoord(const DocRect dr, UserRect* pur)
 
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		dr - DocRect to be converted into tool-specific coordinate space
+	Outputs:	ur - UserRect containing optionally modified version of dr
+	Purpose:	Gives the current tool the chance to change the coordinates
+				displayed on the ruler
 
+********************************************************************************************/
+
+void Tool_v1::GetRulerCoord(const DocRect dr, UserRect* pur)
+{
+	// Override me if you want!
+	// Note that overriding this function implies that you will ensure the redraw of the rulers
+	// as you enter and leave your tool.
+}
+
+
+
+
 /********************************************************************************************
 
+>	virtual BOOL Tool_v1::OnRulerClick( DocCoord PointerPos,
+										ClickType Click,
+										ClickModifiers Mods,
+										Spread* pSpread
+									  )
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		PointerPos	- SpreadCoord of click within spread
+				Click		- Type of click enum
+				Mods		- Modifier flags struct
+				pSpread		- pointer to spread upon which click occurred
+				pRuler		- pointer to ruler which generated click
+	Outputs:	-
+	Returns:	TRUE if this click event was handled
+				FALSE if not
+	Purpose:	Gives the current tool the chance to handle ruler clicks in preference
+				to other handlers
+
+********************************************************************************************/
+
+BOOL Tool_v1::OnRulerClick( DocCoord PointerPos,
+							ClickType Click,
+							ClickModifiers Mods,
+							Spread* pSpread,
+							RulerBase* pRuler
+							)
+{
+	// Override me if you want!
+	return FALSE;
+}
+
+
+
+
+/********************************************************************************************
+
 >	virtual void Tool_v1::CurrentDocViewChange()
 
 	Author:		Justin_Flude (Xara Group Ltd) <camelotdev@xxxxxxxx>
Index: Trunk/XaraLX/wxOil/wincoord.cpp
===================================================================
--- Trunk/XaraLX/wxOil/wincoord.cpp	(revision 1394)
+++ Trunk/XaraLX/wxOil/wincoord.cpp	(revision 1395)
@@ -128,6 +128,26 @@
 
 
 /********************************************************************************************
+>	WinCoord::WinCoord(INT32 x, INT32 y)
+
+	Author: 	Will_Cowling (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	5/8/93
+	Inputs:		Two integers (either signed 16 or 32 bits, depending on the Windows platform).
+	Outputs:	-
+	Returns:	-
+	Purpose:	Constructor for a WinCoord.  Calls CPoint::CPoint(x, y)
+	Errors:		None.
+	See Also:	class CPoint
+
+********************************************************************************************/
+
+WinCoord::WinCoord(wxPoint pt) : wxPoint(pt)
+{
+}
+
+
+
+/********************************************************************************************
 >	OilCoord WinCoord::ToOil(View *pView, BOOL PixelCentre = FALSE) const
 
 	Author: 	Will_Cowling (Xara Group Ltd) <camelotdev@xxxxxxxx>
Index: Trunk/XaraLX/wxOil/oilruler.h
===================================================================
--- Trunk/XaraLX/wxOil/oilruler.h	(revision 1394)
+++ Trunk/XaraLX/wxOil/oilruler.h	(revision 1395)
@@ -101,13 +101,14 @@
 #define INC_OILRULERS
 
 #include "guides.h"
+#include "camview.h"
 
 class WinCoord;
 class WinRect;
 class DovView;
-class CCamView;
 class RulerBase;
 class OILHorizontalRuler;
+class CRenderWnd;
 
 #define MAX_RULER_DIGITS 3
 
@@ -221,19 +222,34 @@
 protected:
 	virtual BOOL IsHorizontal() {return FALSE;}
 	virtual BOOL StartDrag(UINT32 nFlags, wxPoint point);
+	virtual BOOL HandleRulerDragEvent(UINT32 Button, UINT32 nFlags, WinCoord point, ClickType t);
+	virtual BOOL HandleRulerUpEvent(UINT32 Button, WinCoord point);
 
+	CRenderWnd* GetRenderWindow() {return m_pOwnerView ? m_pOwnerView->GetRenderWindow() : NULL;}
+	void SetCurrentStates();
+
 protected:
 	// wxWindows OIL message handlers and related functions
 	void DoPaint(wxDC* pDC);
 
 	void OnPaint(wxPaintEvent &event);
 
-	void OnLButtonDown(wxMouseEvent& event);
-	void OnLButtonDblClk(wxMouseEvent& event);
-	void OnRButtonUp(wxMouseEvent& event);
+//	void OnLButtonDown(wxMouseEvent& event);
+//	void OnLButtonDblClk(wxMouseEvent& event);
+//	void OnRButtonUp(wxMouseEvent& event);
 	void OnMouseMove(wxMouseEvent& event);
 
+	void 	OnLButtonDown( wxMouseEvent &event );
+	void 	OnLButtonDblClk( wxMouseEvent &event );
+	void 	OnLButtonUp( wxMouseEvent &event );
+	void 	OnMButtonDown( wxMouseEvent &event );
+	void 	OnMButtonDblClk( wxMouseEvent &event );
+	void 	OnMButtonUp( wxMouseEvent &event );
+	void 	OnRButtonDown( wxMouseEvent &event );
+	void 	OnRButtonDblClk( wxMouseEvent &event );
+	void 	OnRButtonUp( wxMouseEvent &event );
 
+
 public:
 	static String_256*	FontName;		// read from .ini file
 	static INT32        FontSize;
@@ -245,6 +261,7 @@
 	static INT32 		CharWidth;
 
 	// vars to pass info from OIL OnPaint() to low level OIL render funtions, transparent to intermediate kernel code
+	// This is a bit NASTY!
 	static wxDC* 		pPaintDC;
 	static DocView*  	pPaintDocView;
 	static wxSize     	RulerToDocOffset;
@@ -254,6 +271,12 @@
 	CCamView*			m_pOwnerView;
 	RulerBase*			pKernelRuler;
 
+	ClickType			m_LastClickType;		// click type of last START_DRAG
+	UINT32				m_LastClickButton;		// buttons down on last START_DRAG
+	wxPoint				m_LastClickPoint;		// mouse position of last START_DRAG
+	ClickModifiers		m_LastClickMods;		// ClickMods on last mouse event (NOT modified by button-up events!)
+	UINT32 				m_FirstClickButton;		// Which button started the drag (if dragging).
+
 	BOOL InDrag;
 
 	DECLARE_EVENT_TABLE()
Index: Trunk/XaraLX/wxOil/wincoord.h
===================================================================
--- Trunk/XaraLX/wxOil/wincoord.h	(revision 1394)
+++ Trunk/XaraLX/wxOil/wincoord.h	(revision 1395)
@@ -127,6 +127,7 @@
 public:
 	WinCoord() : wxPoint() {}
 	WinCoord(INT32 x, INT32 y);
+	WinCoord(wxPoint pt);
 
 	OilCoord ToOil(View *pView, BOOL PixelCentre = FALSE) const;
 };
Index: Trunk/XaraLX/wxOil/oilruler.cpp
===================================================================
--- Trunk/XaraLX/wxOil/oilruler.cpp	(revision 1394)
+++ Trunk/XaraLX/wxOil/oilruler.cpp	(revision 1395)
@@ -157,9 +157,15 @@
 IMPLEMENT_DYNAMIC_CLASS(OILRuler, wxWindow)
 
 BEGIN_EVENT_TABLE( OILRuler, wxWindow )
-	EVT_LEFT_DOWN(		OILRuler::OnLButtonDown)
-	EVT_LEFT_DCLICK(	OILRuler::OnLButtonDblClk)
-	EVT_RIGHT_UP(		OILRuler::OnRButtonUp)
+	EVT_LEFT_DOWN( 		OILRuler::OnLButtonDown)
+	EVT_LEFT_DCLICK( 	OILRuler::OnLButtonDblClk)
+	EVT_LEFT_UP( 		OILRuler::OnLButtonUp)
+	EVT_MIDDLE_DOWN( 	OILRuler::OnMButtonDown)
+	EVT_MIDDLE_DCLICK( 	OILRuler::OnMButtonDblClk)
+	EVT_MIDDLE_UP( 	 	OILRuler::OnMButtonUp)
+	EVT_RIGHT_DOWN( 	OILRuler::OnRButtonDown)
+	EVT_RIGHT_DCLICK( 	OILRuler::OnRButtonDblClk)
+	EVT_RIGHT_UP( 	 	OILRuler::OnRButtonUp)
 	EVT_MOTION(			OILRuler::OnMouseMove)
 	EVT_PAINT(			OILRuler::OnPaint)
 END_EVENT_TABLE()
@@ -610,115 +616,460 @@
 
 
 /********************************************************************************************
->	afx_msg void OILRuler::OnLButtonDown(wxMouseEvent& event);
+>	void OILRuler::OnLButtonDown(wxMouseEvent& event);
 
-	Author:		Chris_Parks (Xara Group Ltd) <camelotdev@xxxxxxxx>
-	Created:	5/3/94
-	Inputs:		nFlags - 
-				point  -
-	Purpose:	process LButtonDoown event 
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		event - wxMouseEvent object
+	Outputs:	-
+	Returns:	-
+	Purpose:	Handle mouse event
+
 ********************************************************************************************/
                     
 void OILRuler::OnLButtonDown(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-	UINT32 nFlags = 0;
-	StartDrag(nFlags, event.GetPosition());
+	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
+	BOOL bHandled = HandleRulerDragEvent(MK_LBUTTON, nFlags, (WinCoord)event.GetPosition(), CLICKTYPE_SINGLE);
+
+	if (!bHandled)
+		StartDrag(nFlags, event.GetPosition());
 }
 
 
 /********************************************************************************************
->	void OILRuler::OnRButtonUp(wxMouseEvent& event);
+>	void OILRuler::OnLButtonDblClk(wxMouseEvent& event);
 
 	Author:		Ed_Cornes (Xara Group Ltd) <camelotdev@xxxxxxxx>
-	Created:	9/10/95
+	Created:	7/10/95
 	Inputs:		nFlags - 
-				point  -
-	Purpose:	Handle left button up events - pop-up context sensitive menu
+				point  - 
+	Purpose:	handle left button double clicks
 ********************************************************************************************/
                     
-void OILRuler::OnRButtonUp(wxMouseEvent& event)
+void OILRuler::OnLButtonDblClk(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-//	UINT32 nFlags = 0;
 	wxPoint point = event.GetPosition();
+	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
+	BOOL bHandled = HandleRulerDragEvent(MK_LBUTTON, nFlags, (WinCoord)point, CLICKTYPE_DOUBLE);
 
-	// get a few pointers - no error checking yet!
-	DocView* pDocView = m_pOwnerView->GetDocViewPtr();
-	Spread*  pSpread  = pKernelRuler->GetpRulerPair()->GetpSpread();
-	if (pDocView==NULL || pSpread==NULL)
+	if (!bHandled)
 	{
-		ERROR3("OILRuler::OnLButtonUp() - pDocView==NULL || pSpread==NULL");
-		return;
+		// get a few pointers
+		DocView* pDocView = m_pOwnerView->GetDocViewPtr();
+		Spread*  pSpread  = pKernelRuler->GetpRulerPair()->GetpSpread();
+		if (pDocView==NULL || pSpread==NULL)
+		{
+			ERROR3("OILRuler::OnLButtonDblClk() - pDocView==NULL || pSpread==NULL");
+			return;
+		}
+	
+		OilCoord MouseOilPos    = ClientToOil(pDocView,point);
+		DocCoord MouseSpreadPos = MouseOilPos.ToDoc(pSpread,pDocView).ToSpread(pSpread,pDocView);
+		CSnap SnapObject(pDocView,pSpread);
+		SnapObject.Snap(&MouseSpreadPos,FALSE);
+	
+		if (IsHorizontal())
+			OpNewGuideline::SetNewGuidelineParam(GUIDELINE_VERT, MouseSpreadPos.x);
+		else
+			OpNewGuideline::SetNewGuidelineParam(GUIDELINE_HORZ, MouseSpreadPos.y);
+	
+		OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_NEWGUIDELINE2);
+		if (pOpDesc!=NULL)
+			pOpDesc->Invoke();
+		else
+			ERROR3("OILRuler::OnLButtonDblClk() - FindOpDescriptor(OPTOKEN_NEWGUIDELINE) failed");
 	}
+}
 
-	// convert to spread coords
-	OilCoord MouseOilPos    = ClientToOil(pDocView,point);
-	DocCoord MouseSpreadPos = MouseOilPos.ToDoc(pSpread,pDocView).ToSpread(pSpread,pDocView);
-	CSnap SnapObject(pDocView,pSpread);
-	SnapObject.Snap(&MouseSpreadPos,FALSE);
 
-	// precharge static buffer with all the info to insert a new guide
-	// at the click point on the off chance this is the option the user chooses from
-	// the menu - as it is not poosible to pass params via the pop-up menu system
-	if (IsHorizontal())
-		GuidelinePropDlg::SetNewGuidelineParams(GUIDELINE_VERT, MouseSpreadPos.x);
-	else
-		GuidelinePropDlg::SetNewGuidelineParams(GUIDELINE_HORZ, MouseSpreadPos.y);
-//	// insert immediate (witout dialog)
-//	if (IsHorizontal())
-//		OpNewGuideline::SetNewGuidelineParam(GUIDELINE_VERT, MouseSpreadPos.x);
-//	else
-//		OpNewGuideline::SetNewGuidelineParam(GUIDELINE_HORZ, MouseSpreadPos.y);
+/********************************************************************************************
+>	void OILRuler::OnLButtonUp(wxMouseEvent& event);
 
-	RulerContextMenu* pRulerMenu = new RulerContextMenu;
-	pRulerMenu->Show();
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		event - wxMouseEvent object
+	Outputs:	-
+	Returns:	-
+	Purpose:	Handle mouse event
+
+********************************************************************************************/
+                    
+void OILRuler::OnLButtonUp(wxMouseEvent& event)
+{
+	BOOL bHandled = HandleRulerUpEvent(MK_LBUTTON, (WinCoord)event.GetPosition());
+
+	if (!bHandled)
+	{
+		// We do nothing in this case
+	}
 }
 
 
 /********************************************************************************************
->	void OILRuler::OnLButtonDblClk(wxMouseEvent& event);
+>	void OILRuler::OnMButtonDown(wxMouseEvent& event);
 
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		event - wxMouseEvent object
+	Outputs:	-
+	Returns:	-
+	Purpose:	Handle mouse event
+
+********************************************************************************************/
+                    
+void OILRuler::OnMButtonDown(wxMouseEvent& event)
+{
+	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
+	BOOL bHandled = HandleRulerDragEvent(MK_MBUTTON, nFlags, (WinCoord)event.GetPosition(), CLICKTYPE_SINGLE);
+
+	if (!bHandled)
+	{
+		// We do nothing in this case
+	}
+}
+
+
+/********************************************************************************************
+>	void OILRuler::OnMButtonDblClk(wxMouseEvent& event);
+
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		event - wxMouseEvent object
+	Outputs:	-
+	Returns:	-
+	Purpose:	Handle mouse event
+
+********************************************************************************************/
+                    
+void OILRuler::OnMButtonDblClk(wxMouseEvent& event)
+{
+	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
+	BOOL bHandled = HandleRulerDragEvent(MK_MBUTTON, nFlags, event.GetPosition(), CLICKTYPE_DOUBLE);
+
+	if (!bHandled)
+	{
+		// We do nothing in this case
+	}
+}
+
+
+/********************************************************************************************
+>	void OILRuler::OnMButtonUp(wxMouseEvent& event);
+
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		event - wxMouseEvent object
+	Outputs:	-
+	Returns:	-
+	Purpose:	Handle mouse event
+
+********************************************************************************************/
+                    
+void OILRuler::OnMButtonUp(wxMouseEvent& event)
+{
+	BOOL bHandled = HandleRulerUpEvent(MK_MBUTTON, event.GetPosition());
+
+	if (!bHandled)
+	{
+		// We do nothing in this case
+	}
+}
+
+
+/********************************************************************************************
+>	void OILRuler::OnRButtonDown(wxMouseEvent& event);
+
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		event - wxMouseEvent object
+	Outputs:	-
+	Returns:	-
+	Purpose:	Handle mouse event
+
+********************************************************************************************/
+                    
+void OILRuler::OnRButtonDown(wxMouseEvent& event)
+{
+	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
+	BOOL bHandled = HandleRulerDragEvent(MK_RBUTTON, nFlags, event.GetPosition(), CLICKTYPE_SINGLE);
+
+	if (!bHandled)
+	{
+		// We do nothing in this case
+	}
+}
+
+
+/********************************************************************************************
+>	void OILRuler::OnRButtonDblClk(wxMouseEvent& event);
+
+	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	30/Jun/2006
+	Inputs:		event - wxMouseEvent object
+	Outputs:	-
+	Returns:	-
+	Purpose:	Handle mouse event
+
+********************************************************************************************/
+                    
+void OILRuler::OnRButtonDblClk(wxMouseEvent& event)
+{
+	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
+	BOOL bHandled = HandleRulerDragEvent(MK_RBUTTON, nFlags, event.GetPosition(), CLICKTYPE_DOUBLE);
+
+	if (!bHandled)
+	{
+		// We do nothing in this case
+	}
+}
+
+
+/********************************************************************************************
+>	void OILRuler::OnRButtonUp(wxMouseEvent& event);
+
 	Author:		Ed_Cornes (Xara Group Ltd) <camelotdev@xxxxxxxx>
-	Created:	7/10/95
+	Created:	9/10/95
 	Inputs:		nFlags - 
-				point  - 
-	Purpose:	handle left button double clicks
+				point  -
+	Purpose:	Handle left button up events - pop-up context sensitive menu
 ********************************************************************************************/
                     
-void OILRuler::OnLButtonDblClk(wxMouseEvent& event)
+void OILRuler::OnRButtonUp(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-//	UINT32 nFlags = 0;
 	wxPoint point = event.GetPosition();
+	BOOL bHandled = HandleRulerUpEvent(MK_RBUTTON, point);
 
-	// get a few pointers
+	if (!bHandled)
+	{
+		// get a few pointers - no error checking yet!
+		DocView* pDocView = m_pOwnerView->GetDocViewPtr();
+		Spread*  pSpread  = pKernelRuler->GetpRulerPair()->GetpSpread();
+		if (pDocView==NULL || pSpread==NULL)
+		{
+			ERROR3("OILRuler::OnLButtonUp() - pDocView==NULL || pSpread==NULL");
+			return;
+		}
+	
+		// convert to spread coords
+		OilCoord MouseOilPos    = ClientToOil(pDocView,point);
+		DocCoord MouseSpreadPos = MouseOilPos.ToDoc(pSpread,pDocView).ToSpread(pSpread,pDocView);
+		CSnap SnapObject(pDocView,pSpread);
+		SnapObject.Snap(&MouseSpreadPos,FALSE);
+	
+		// precharge static buffer with all the info to insert a new guide
+		// at the click point on the off chance this is the option the user chooses from
+		// the menu - as it is not poosible to pass params via the pop-up menu system
+		if (IsHorizontal())
+			GuidelinePropDlg::SetNewGuidelineParams(GUIDELINE_VERT, MouseSpreadPos.x);
+		else
+			GuidelinePropDlg::SetNewGuidelineParams(GUIDELINE_HORZ, MouseSpreadPos.y);
+	//	// insert immediate (witout dialog)
+	//	if (IsHorizontal())
+	//		OpNewGuideline::SetNewGuidelineParam(GUIDELINE_VERT, MouseSpreadPos.x);
+	//	else
+	//		OpNewGuideline::SetNewGuidelineParam(GUIDELINE_HORZ, MouseSpreadPos.y);
+	
+		RulerContextMenu* pRulerMenu = new RulerContextMenu;
+		pRulerMenu->Show();
+	}
+}
+
+
+
+
+/********************************************************************************************
+>	BOOL OILRuler::HandleRulerDragEvent(UINT32 Button, UINT32 nFlags, wxPoint point, ClickType t)
+
+	Author:		Justin_Flude (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	ages ago
+	Inputs:		Button - the actual button being pressed for a click/double click event.
+				nFlags - The mouse button flags
+				point - the coordinate of the mouse cursor
+				t -  the kind of mouse event (button up/down, move, drag start/finish etc.)
+	Outputs:	-
+	Returns:    -
+	Purpose:    Gathers together Windows information about a mouse event and passes it on to
+				the kernel, by calling DocView::OnClick()
+				HandleDragEvent needs to be called from OnTimer code so rather than 
+				synthesizing a wxMouseEvent object this function has been left taking 
+				non-wx params
+	Errors:		-
+	Scope:		Private
+	SeeAlso:	CCamView::GetClickMods(); CCamView::OnLButtonDown(); CCamView::OnRButtonDown()
+				DocView::OnClick()
+
+********************************************************************************************/ 
+
+/********************************************************************************************
+
+Technical notes (by Tim):
+
+The Button is parameter is necessary, because sometimes when we get the *first* button
+down event, nFlags has more than one mouse button bit set.  This only happens when you
+rampantly click buttons very quickly but nevertheless we *do* need to know which button
+was pressed, otherwise we never release the drag event and we end up with button-up-drag
+city.
+
+I assume this is due to some latency in Windows, e.g., it gets a button down event, and
+while preparing it goes and reads the mouse button state and meanwhile another button has
+been pressed so we get a button down event with nFlags indicating more than one button
+is down.
+
+********************************************************************************************/ 
+
+BOOL OILRuler::HandleRulerDragEvent(UINT32 Button, UINT32 nFlags, WinCoord point, ClickType t)
+{
+	if (pKernelRuler==NULL)
+		return FALSE;
+
 	DocView* pDocView = m_pOwnerView->GetDocViewPtr();
-	Spread*  pSpread  = pKernelRuler->GetpRulerPair()->GetpSpread();
-	if (pDocView==NULL || pSpread==NULL)
+
+	if (DocView::GetSelected() != pDocView)
 	{
-		ERROR3("OILRuler::OnLButtonDblClk() - pDocView==NULL || pSpread==NULL");
-		return;
+		// If selected doc is null, let's select it anyway.
+		if (DocView::GetSelected() == NULL)
+		{
+			// We're in a weird state that should never happen but does - a document
+			// has the focus, but isn't selected
+			Document* pKDoc =NULL;
+			if(pDocView)
+				pKDoc = pDocView->GetDoc();
+
+			if (pKDoc)
+			{
+				Document::SetSelectedViewAndSpread(pKDoc, pDocView, NULL);
+			}
+			
+		}
+		return FALSE;
 	}
 
-	OilCoord MouseOilPos    = ClientToOil(pDocView,point);
-	DocCoord MouseSpreadPos = MouseOilPos.ToDoc(pSpread,pDocView).ToSpread(pSpread,pDocView);
-	CSnap SnapObject(pDocView,pSpread);
-	SnapObject.Snap(&MouseSpreadPos,FALSE);
+	SetCurrentStates();
 
-	if (IsHorizontal())
-		OpNewGuideline::SetNewGuidelineParam(GUIDELINE_VERT, MouseSpreadPos.x);
+	// Find out which buttons etc are down.
+	m_LastClickMods = ClickModifiers::GetClickModifiers(nFlags);
+
+	// If it's the first single click, then reset the drag delay timer, and ask for a 
+	// Windows timer.
+	if (((t == CLICKTYPE_SINGLE) || (t == CLICKTYPE_DOUBLE)) && 
+		(m_FirstClickButton == 0))
+	{
+		// Remember this event.
+		m_LastClickPoint = point;
+		m_LastClickType = t;
+		m_LastClickButton = Button;
+		m_FirstClickButton = Button;
+//		m_DragTimer.Sample();
+
+		// Ask the system for a timer.
+		// The timer is used to generate DragPointerIdle events, which are not directly
+		// supported by Windows.
+//		UINT32 rate = 100;
+PORTNOTE("other","Removed reading of keyboard autorepeat rate")
+#ifndef EXCLUDE_FROM_XARALX
+		::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &rate, 0);
+#endif
+
+//		m_DragIdleTimer.Start(rate);
+	}
+
+	// Convert the click position to OIL coordinates before passing to the kernel.
+	OilCoord ocoord = ClientToOil(pDocView, point);
+	return pKernelRuler->OnRulerClick(ocoord, t, m_LastClickMods);
+}
+
+
+
+/*********************************************************************************************
+>	BOOL OILRuler::HandleRulerUpEvent(UINT32 Button, WinCoord point)
+
+	Author:		Justin_Flude (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	9th Sept 1993
+	Inputs:		Button - which mouse button has been released.
+				nFlags - The mouse button flags.
+				point - the coordinate of the mouse cursor.
+	Outputs:	-
+	Returns:    -
+	Purpose:    Finishes the current drag, if there is one, by elucidating the state of
+				the buttons etc and calling DragDFinished() in the kernel (DocView).  Called
+				whenever a mouse button is released.
+	Errors:		-
+	Scope:		Private
+	SeeAlso:	CCamView::GetClickMods(); CCamView::OnLButtonDown(); CCamView::OnRButtonDown()
+				DocView::OnClick()
+
+**********************************************************************************************/ 
+
+BOOL OILRuler::HandleRulerUpEvent(UINT32 Button, WinCoord point)
+{
+	if (pKernelRuler==NULL)
+		return FALSE;
+
+	DocView* pDocView = m_pOwnerView->GetDocViewPtr();
+
+	if (DocView::GetSelected() != pDocView)
+	{
+//		ENSURE(pCurrentDragOp == NULL, "Drag operation in a view that isn't 'selected' !!");
+		return FALSE;
+	}
+
+	// Set Current states...
+	SetCurrentStates();
+
+	// Convert WinCoord click point to OilCoord AND take any ruler offsets into account
+	OilCoord ocoord = ClientToOil(pDocView, point);
+
+	// Was the button that went up the first one that went down?
+	if (Button==m_FirstClickButton)
+	{
+		//Yes it was.
+		//Is there a drag currently running?
+/*		if (m_pCurrentDragOp != NULL)
+		{
+			// Yes there is.
+			// Release the capture and terminate the drag.  Note that we try to release
+			// the mouse capture as soon as possible after a drag has finished, in case the
+			// DragFinished method below brings up a dialog box or something.
+			if (GetRenderWindow() && GetRenderWindow()->GetCapture()==GetRenderWindow())
+				GetRenderWindow()->ReleaseMouse();
+			return pKernelRuler->DragFinished(m_pCurrentDragOp, ocoord, m_LastClickMods, TRUE);
+
+		}
+		else
+*/		{
+			// No drag is currently running
+			// Kill the timer started in HandleDragEvent(), 
+			// as we don't want to wait for a drag anymore.
+//			m_DragIdleTimer.Stop();
+
+			m_FirstClickButton = 0;
+
+			//Then pass the Up-Click message to CCamView::OnClick
+			return pKernelRuler->OnRulerClick(ocoord, CLICKTYPE_UP, m_LastClickMods);
+		}
+	}
 	else
-		OpNewGuideline::SetNewGuidelineParam(GUIDELINE_HORZ, MouseSpreadPos.y);
+	{
+		//No, the button that went up was not the first one to go down.
+		//In that case, we expect the first button that went down is still down and
+		//hence there is a drag running.
+		//Is there a drag running?
+/*		if (m_pCurrentDragOp != NULL)
+		{
+			//Yes, as expected.
+			//Pass the Up-Click message to CCamView::OnClick
+			return pKernelRuler->OnRulerClick(ocoord, CLICKTYPE_UP, m_LastClickMods);
+		}
+*/
+	}
 
- 	OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_NEWGUIDELINE2);
-	if (pOpDesc!=NULL)
-		pOpDesc->Invoke();
-	else
-		ERROR3("OILRuler::OnLButtonDblClk() - FindOpDescriptor(OPTOKEN_NEWGUIDELINE) failed");
+	return FALSE;
 }
 
 
+
+
 /********************************************************************************************
 >	void OILRuler::OnMouseMove(wxMouseEvent& event);
 
@@ -731,8 +1082,7 @@
                     
 void OILRuler::OnMouseMove(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-//	UINT32 nFlags = 0;
+//	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
 	wxPoint MousePos = event.GetPosition();
 
 	static wxPoint OldMousePos = wxPoint(0,0);
@@ -1039,6 +1389,32 @@
 }
 
 
+/********************************************************************************************
+>	void OILRuler::SetCurrentStates()
+
+	Author:		Chris_Parks (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	15/6/96
+	Inputs:		-
+	Purpose:	Set the  View and Document current
+	SeeAlso:	
+********************************************************************************************/
+
+void OILRuler::SetCurrentStates()
+{
+	if (m_pOwnerView)
+	{
+		DocView* pDocView = m_pOwnerView->GetDocViewPtr();
+		if (pDocView)
+		{
+			pDocView->SetCurrent();
+			Document* pKernelDoc = pDocView->GetDoc();
+			if (pKernelDoc)
+				pKernelDoc->SetCurrent();
+		}
+	}
+}
+
+
 /////////////////////////////////////////////////////////////////////////////////////////////
 // 				OILHorizontalRuler
 /////////////////////////////////////////////////////////////////////////////////////////////
@@ -1651,8 +2027,7 @@
                     
 void OriginGadget::OnLButtonDown(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-	UINT32 nFlags = 0;
+	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
 	wxPoint point = event.GetPosition();
 
 	String_256 OpToken(OPTOKEN_SPREADORIGIN);
@@ -1674,8 +2049,7 @@
                     
 void OriginGadget::OnRButtonUp(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-//	UINT32 nFlags = 0;
+//	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
 	wxPoint point = event.GetPosition();
 
 	OriginContextMenu* pOriginMenu = new OriginContextMenu;
@@ -1695,8 +2069,7 @@
                     
 void OriginGadget::OnLButtonDblClk(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-//	UINT32 nFlags = 0;
+	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
 	wxPoint point = event.GetPosition();
 
 	if (OpResetSpreadOrigin::GetState(NULL,NULL).Greyed==FALSE)
@@ -1722,8 +2095,7 @@
                     
 void OriginGadget::OnMouseMove(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-//	UINT32 nFlags = 0;
+//	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
 	wxPoint MousePos = event.GetPosition();
 
 	static wxPoint OldMousePos = wxPoint(0,0);
@@ -2097,8 +2469,7 @@
                     
 void LegendLabel::OnMouseMove(wxMouseEvent& event)
 {
-	PORTNOTE("ruler", "TODO: Set nFlags");
-//	UINT32 nFlags = 0;
+//	UINT32 nFlags = ClickModifiers::SynthesizeMouseEventFlags(event);
 	wxPoint MousePos = event.GetPosition();
 
 	static wxPoint OldMousePos = wxPoint(0,0);


Xara