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

[XaraXtreme-dev] Ruler extensions



OK, time to check in all the new text formatting code. I will try and 
do it in stages. First of all, the new ruler infrastructure allowing 
tools to render graphics on the ruler, handle clicks and start drags.

Martin
Index: wxOil/oilruler.h
===================================================================
--- wxOil/oilruler.h	(Revision 1442)
+++ wxOil/oilruler.h	(Arbeitskopie)
@@ -204,6 +204,9 @@
 
 	virtual BOOL DrawMajorGraticule(OilCoord GratOilPos, LPCTSTR str) {return FALSE;}
 	virtual BOOL DrawMinorGraticule(OilCoord GratOilPos, INT32 ExtraSize=0);
+	BOOL HighlightSection(OilCoord Lo, OilCoord Hi);
+	BOOL DrawBitmap(OilCoord Pos, ResourceID BitmapID);
+	BOOL StartToolDrag(UINT32 nFlags, OilCoord point, String_256* OpToken, OpParam* Param);
 
 	BOOL PaintMouseFollower(OilCoord OilPos, DocView* pDocView, MouseFollowerRenderType RenderType);
 	BOOL  DrawMouseFollower(OilCoord OilPos, DocView* pDocView, MouseFollowerRenderType RenderType, wxDC* pDC);
Index: wxOil/oilruler.cpp
===================================================================
--- wxOil/oilruler.cpp	(Revision 1442)
+++ wxOil/oilruler.cpp	(Arbeitskopie)
@@ -341,7 +341,32 @@
 	return TRUE;
 }
 
+/********************************************************************************************
+>	BOOL OILRuler::StartToolDrag(UINT32 nFlags, wxPoint point, String_256* OpToken, void* Params)
 
+	Author:		Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+	Created:	12/07/06
+	Input:      nFlags - the mouse event flags (as passed to OnRulerClick)
+				point - the pointer position (as passed to OnRulerClick)
+				OpToken - name of the operation to invoke
+				Params - an opaque pointer to the parameters for the operation
+	Returns:	FALSE if fails
+	Purpose:	StartDrag function for tool drags.
+********************************************************************************************/
+                    
+BOOL OILRuler::StartToolDrag(UINT32 nFlags, OilCoord point, String_256* pOpToken, OpParam* pParam)
+{ 
+	if (m_pOwnerView != NULL)
+	{
+		DocView* pDocView = m_pOwnerView->GetDocViewPtr();
+		wxPoint ClientPoint = point.ToWin(pDocView);
+		m_pOwnerView->InvokeDragOp(pOpToken, pParam, nFlags, ClientPoint);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 /*********************************************************************************************
 >	void OILRuler::ShowRuler(BOOL show)
 
@@ -976,7 +1001,7 @@
 
 	// Convert the click position to OIL coordinates before passing to the kernel.
 	OilCoord ocoord = ClientToOil(pDocView, point);
-	return pKernelRuler->OnRulerClick(ocoord, t, m_LastClickMods);
+	return pKernelRuler->OnRulerClick(nFlags, ocoord, t, m_LastClickMods);
 }
 
 
@@ -1046,7 +1071,7 @@
 			m_FirstClickButton = 0;
 
 			//Then pass the Up-Click message to CCamView::OnClick
-			return pKernelRuler->OnRulerClick(ocoord, CLICKTYPE_UP, m_LastClickMods);
+			return pKernelRuler->OnRulerClick(0, ocoord, CLICKTYPE_UP, m_LastClickMods);
 		}
 	}
 	else
@@ -1388,8 +1413,93 @@
 	return TRUE;
 }
 
+/********************************************************************************************
+>	BOOL OILRuler::HighlightSection(OilCoord Lo, OilCoord Hi)
 
+	Author:		Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+	Created:	07/07/06
+	Inputs:		Lo, Hi - determines the ruler section to be redrawn
+	Returns:    FALSE if fails
+	Purpose:	Highlight a rectangular section of the ruler
+
+********************************************************************************************/
+
+BOOL OILRuler::HighlightSection(OilCoord Lo, OilCoord Hi)
+{
+	ERROR2IF(pPaintDC==NULL,FALSE,"OILRuler::HighlightSection - pPaintDC==NULL");
+
+	// convert to ruler relative win coords
+	WinCoord RectLoWinPos = Lo.ToWin(pPaintDocView);
+	WinCoord RectHiWinPos = Hi.ToWin(pPaintDocView);
+
+	RectLoWinPos -= RulerToDocOffset;
+	RectHiWinPos -= RulerToDocOffset;
+
+	if (IsHorizontal())
+	{
+		RectLoWinPos.y = 0;
+		Hi.y = RenderWidth;
+	}
+	else
+	{
+		Lo.x = 0;
+		Hi.x = RenderWidth;
+	}
+
+	WinRect HighlightWinRect(RectLoWinPos.x, RectLoWinPos.y, RectHiWinPos.x, RectHiWinPos.y);
+
+	pPaintDC->SetBrush(wxBrush(wxColour(*wxWHITE)));
+	pPaintDC->SetPen(*wxTRANSPARENT_PEN);
+	pPaintDC->DrawRectangle(HighlightWinRect);
+	pPaintDC->SetPen(wxPen(*wxBLACK, 1, wxSOLID));		// Restore previous pen (as expected by further drawing)
+	return TRUE;
+}
+
 /********************************************************************************************
+>	BOOL OILRuler::DrawBitmap(OilCoord Pos, ResourceID BitmapID)
+
+	Author:		Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+	Created:	07/07/06
+	Inputs:		Pos - the position on the ruler (only ordinate in ruler direction is significant)
+				BitmapID - the resource id of the bitmap
+	Returns:    FALSE if fails
+	Purpose:	Display a bitmap at a specific ruler position, centered around the requested
+				position in the ruler direction, aligned with the ruler edge in the other
+				direction
+	
+********************************************************************************************/
+
+BOOL OILRuler::DrawBitmap(OilCoord Pos, ResourceID BitmapID)
+{
+	ERROR2IF(pPaintDC==NULL,FALSE,"OILRuler::DrawBitmap() - pPaintDC==NULL");
+
+	wxBitmap* pBitmap = CamArtProvider::Get()->FindBitmap(BitmapID);
+	ERROR2IF(pBitmap==NULL,FALSE,"OILRuler::DrawBitmap - could not find bitmap");
+
+	INT32 BitmapWidth = pBitmap->GetWidth();
+	INT32 BitmapHeight = pBitmap->GetHeight();
+
+	// convert to ruler relative win coords
+	WinCoord WinPos = Pos.ToWin(pPaintDocView);
+	WinPos -= RulerToDocOffset;
+
+	if (IsHorizontal())
+	{
+		// centered around requested position, aligned with bottom of ruler
+		WinPos.x -= BitmapWidth / 2;
+		WinPos.y = RenderWidth - BitmapHeight;
+	}
+	else
+	{
+		// centered around requested position, aligned with right hand side of ruler
+		WinPos.x = RenderWidth - BitmapWidth;
+		WinPos.y -= BitmapHeight / 2;
+	}
+	pPaintDC->DrawBitmap(*pBitmap, WinPos.x, WinPos.y, true);
+	return TRUE;
+}
+
+/********************************************************************************************
 >	void OILRuler::SetCurrentStates()
 
 	Author:		Chris_Parks (Xara Group Ltd) <camelotdev@xxxxxxxx>
Index: Kernel/rulers.cpp
===================================================================
--- Kernel/rulers.cpp	(Revision 1442)
+++ Kernel/rulers.cpp	(Arbeitskopie)
@@ -179,9 +179,6 @@
 	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);
@@ -189,6 +186,16 @@
 	if (GetOrd(UpdateRect.hi)<GetOrd(UpdateRect.lo))
 		return TRUE;	// no region to redraw
 
+	// Give the current tool the chance to modify the UserCoord displayed by the ruler
+	UserCoord Offsets(0, 0);
+	if (Tool::GetCurrent())
+		Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
+	UpdateRect.Translate(-Offsets.x, -Offsets.y);
+
+	// allow the current tool to render background blobs
+	if (Tool::GetCurrent())
+		Tool::GetCurrent()->RenderRulerBlobs(this, UpdateRect, TRUE);
+
 	// find the first and last major graticules to be rendered
 	double Start = GetOrd(UpdateRect.lo)/pRD->GratStepSize;
 	double End   = GetOrd(UpdateRect.hi)/pRD->GratStepSize;
@@ -201,7 +208,7 @@
 	while (Grat<=LastGrat)
 	{
 		// calc position of graticule and convert to OilCoords
-		MILLIPOINT GratPos=(MILLIPOINT)(Grat*pRD->GratUnitSize);
+		MILLIPOINT GratPos=(MILLIPOINT)(Grat*pRD->GratUnitSize + GetOrd(Offsets));
 		OilCoord GratOilPos=MakeCoord(GratPos).ToSpread(pSpread).ToOil(pSpread,pDocView);
 
 		// draw major graticule
@@ -230,6 +237,10 @@
 		Grat+=pRD->GratStep;
 	}
 
+	// allow the current tool to render foreground blobs
+	if (Tool::GetCurrent())
+		Tool::GetCurrent()->RenderRulerBlobs(this, UpdateRect, FALSE);
+
 	// draw the mouse follower on this ruler in it's last drawn position
 	DocCoord LastPos    = pRulerPair->GetMouseFollowerPosition();
 	BOOL     Visibility = pRulerPair->GetMouseFollowerVisibility();
@@ -244,7 +255,68 @@
 	return TRUE;
 }
 
+/*****************************************************************************
+>	BOOL RulerBase::HighlightSection(MILLIPOINT ord_lo, MILLIPOINT ord_hi)
 
+	Author:		Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+	Created:	07/07/06
+	Inputs:		ord_lo, ord_hi - low and high coordinate on the ruler in tool user
+								 space (i.e., we know about the tool's own ruler origin)
+	Returns:	FALSE if fails
+	Purpose:	Highlight a rectangular section of the ruler
+
+*****************************************************************************/
+
+BOOL RulerBase::HighlightSection(MILLIPOINT ord_lo, MILLIPOINT ord_hi)
+{
+	DocView*         pDocView = pRulerPair->GetpDocView();
+	Spread*          pSpread  = pRulerPair->GetpSpread();
+
+	// if no spread visible in doc view, just exit
+	if (pSpread==NULL) return TRUE;
+
+	// take the current tool ruler origin into account
+	UserCoord Offsets(0, 0);
+	if (Tool::GetCurrent())
+		Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
+	ord_lo += GetOrd(Offsets); ord_hi += GetOrd(Offsets);
+
+	OilCoord OilPosLo = MakeCoord(ord_lo).ToSpread(pSpread).ToOil(pSpread,pDocView);
+	OilCoord OilPosHi = MakeCoord(ord_hi).ToSpread(pSpread).ToOil(pSpread,pDocView);
+	return pOILRuler->HighlightSection(OilPosLo, OilPosHi);
+}
+
+/*****************************************************************************
+>	BOOL RulerBase::DrawBitmap(MILLIPOINT ord, ResourceID BitmapID)
+
+	Author:		Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+	Created:	07/07/06
+	Inputs:		ord - the position on the ruler in tool user space
+				(i.e., we know about the tool's own ruler origin)
+				BitmapID - the resource id of the bitmap
+	Returns:	FALSE if fails
+	Purpose:	Draw a bitmap at a specific position in the ruler
+
+*****************************************************************************/
+
+BOOL RulerBase::DrawBitmap(MILLIPOINT ord, ResourceID BitmapID)
+{
+	DocView*         pDocView = pRulerPair->GetpDocView();
+	Spread*          pSpread  = pRulerPair->GetpSpread();
+
+	// if no spread visible in doc view, just exit
+	if (pSpread==NULL) return TRUE;
+
+	// take the current tool ruler origin into account
+	UserCoord Offsets(0, 0);
+	if (Tool::GetCurrent())
+		Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
+	ord += GetOrd(Offsets);
+
+	OilCoord OilPos = MakeCoord(ord).ToSpread(pSpread).ToOil(pSpread,pDocView);
+	return pOILRuler->DrawBitmap(OilPos, BitmapID);
+}
+
 /********************************************************************************************
 
 > 	BOOL RulerBase::OnRulerClick(OilCoord PointerPos, ClickType Click, ClickModifiers Mods)
@@ -265,7 +337,7 @@
 
 ********************************************************************************************/
 
-BOOL RulerBase::OnRulerClick(OilCoord PointerPos, ClickType Click, ClickModifiers Mods)
+BOOL RulerBase::OnRulerClick(UINT32 nFlags, OilCoord PointerPos, ClickType Click, ClickModifiers Mods)
 {
 	ERROR3IF(pRulerPair==NULL, "pRulerPair unexpectedly NULL");
 	ERROR3IF(pRulerPair->GetpSpread()==NULL, "pRulerPair->pSpread unexpectedly NULL");
@@ -295,18 +367,40 @@
 
 	// 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);
+	UserCoord UserPos = DocPos.ToUser(pSpread);
 
+	// take the current tool ruler origin into account
+	UserCoord Offsets(0, 0);
 	if (Tool::GetCurrent())
-		return Tool::GetCurrent()->OnRulerClick(DocPos, Click, Mods, pSpread, this);
+		Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
+	UserPos.translate(-Offsets.x, -Offsets.y);
 
+	if (Tool::GetCurrent())
+		return Tool::GetCurrent()->OnRulerClick(nFlags, UserPos, Click, Mods, pSpread, this);
+
 	return FALSE;
 }
 
+BOOL RulerBase::StartToolDrag(UINT32 nFlags, UserCoord PointerPos, String_256* pOpToken, OpParam* pParam)
+{
+	// Find the spread in which the click happened
+	Spread *pSpread = pRulerPair->GetpSpread();
+	DocView *pDocView = pRulerPair->GetpDocView();
 
+	// take the current tool ruler origin into account
+	UserCoord Offsets(0, 0);
+	if (Tool::GetCurrent())
+		Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
+	PointerPos.translate(Offsets.x, Offsets.y);
 
+	OilCoord OilPos = PointerPos.ToSpread(pSpread).ToOil(pSpread,pDocView);
+	return pOILRuler->StartToolDrag(nFlags, OilPos, pOpToken, pParam);
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 // HorizontalRuler class
 
@@ -504,7 +598,9 @@
 	UserRect PasteBoardUserRect = PasteSpreadRect.ToUser(pSpread);
 
 	// Give the current tool the chance to modify the UserCoord displayed by the ruler
-	Tool::GetCurrent()->GetRulerCoord(PasteSpreadRect, &PasteBoardUserRect);
+	UserCoord Offsets(0, 0);
+	Tool::GetCurrent()->GetRulerOrigin(pSpread, &Offsets);
+	PasteBoardUserRect.Translate(-Offsets.x, -Offsets.y);
 
 	// hence the start and end values in terms of ruler units
 	double XStart = fabs(PasteBoardUserRect.lo.x/GratStepSize)*GratStep;
Index: Kernel/rulers.h
===================================================================
--- Kernel/rulers.h	(Revision 1442)
+++ Kernel/rulers.h	(Arbeitskopie)
@@ -134,11 +134,23 @@
 
 	virtual MILLIPOINT    GetOrd(const UserCoord& coord) = 0;
 	virtual UserCoord  MakeCoord(const MILLIPOINT ord)   = 0;
+	virtual BOOL    IsHorizontal()                       = 0;
 
+	// Called by the OIL ruler when the ruler needs to be redrawn.
+	// We do all the platform independent computations and call the
+	// OIL ruler back to render specific things (e.g., graticules)
 	BOOL Redraw(OilRect* pOilRect);
 
-	virtual BOOL OnRulerClick(OilCoord, ClickType, ClickModifiers);
+	// For use by tools that wish to render extra things on the ruler
+	// (by responding to the RenderRulerBlobs method)
+	BOOL HighlightSection(MILLIPOINT ord_lo, MILLIPOINT ord_hi);
+	BOOL DrawBitmap(MILLIPOINT ord, ResourceID BitmapID);
+	// Allow tools to start a drag after receiving an OnRulerClick call.
+	// Drag events will be dispatched via OnRulerClick.
+	BOOL StartToolDrag(UINT32 nFlags, UserCoord, String_256* pOpToken, OpParam* pParam);
 
+	virtual BOOL OnRulerClick(UINT32 nFlags, OilCoord, ClickType, ClickModifiers);
+
 protected:
 	RulerPair* pRulerPair;
 	OILRuler*  pOILRuler;
@@ -163,6 +175,7 @@
 
 	virtual MILLIPOINT    GetOrd(const UserCoord& coord) { return coord.x; }
 	virtual UserCoord  MakeCoord(const MILLIPOINT ord)   { return UserCoord(ord,0); }
+	virtual BOOL    IsHorizontal() { return TRUE; }
 };
 
 
@@ -184,6 +197,7 @@
 
 	virtual MILLIPOINT    GetOrd(const UserCoord& coord) { return coord.y; }
 	virtual UserCoord  MakeCoord(const MILLIPOINT ord)   { return UserCoord(0,ord); }
+	virtual BOOL    IsHorizontal() { return FALSE; }
 };
 
 
Index: Kernel/tool.h
===================================================================
--- Kernel/tool.h	(Revision 1442)
+++ Kernel/tool.h	(Arbeitskopie)
@@ -360,10 +360,14 @@
 	virtual void SelectChange(BOOL IsSelected);
 
 	// Allow the Current Tool to modify coordinates displayed on the Ruler
-	virtual void GetRulerCoord(const DocRect, UserRect*);
+	virtual void GetRulerOrigin(Spread* pSpread, UserCoord*);
 
+	// Allow the current tool to render additional blobs on the Ruler
+	virtual void RenderRulerBlobs(RulerBase* pRuler, UserRect& UpdateRect, BOOL IsBackground);
+
 	// Allow the Current Tool to handle Ruler clicks
-	virtual BOOL OnRulerClick( DocCoord PointerPos,
+	virtual BOOL OnRulerClick( UINT32 nFlags,
+							   UserCoord PointerPos,
 							   ClickType Click,
 							   ClickModifiers Mods,
 							   Spread* pSpread,
Index: Kernel/tool.cpp
===================================================================
--- Kernel/tool.cpp	(Revision 1442)
+++ Kernel/tool.cpp	(Arbeitskopie)
@@ -116,6 +116,7 @@
 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
 #include "blobs.h"
 #include "toolmsg.h"
+#include "usercord.h"
 
 #define SELECTED TRUE
 #define DESELECTED FALSE
@@ -1525,27 +1526,49 @@
 
 /********************************************************************************************
 
->	virtual void Tool_v1::GetRulerCoord(const DocRect dr, UserRect* pur)
+>	void Tool_v1::GetRulerOrigin(Spread* pSpread, UserCoord* pOffsets)
 
 	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
+	Inputs:		pSpread - the spread for which the ruler is displayed
+	Outputs:	pOffsets - the desired origin shift in user space (is initialised to 0,0)
 	Purpose:	Gives the current tool the chance to change the coordinates
 				displayed on the ruler
 
 ********************************************************************************************/
 
-void Tool_v1::GetRulerCoord(const DocRect dr, UserRect* pur)
+void Tool_v1::GetRulerOrigin(Spread* pSpread, UserCoord* pOffsets)
 {
 	// 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.
 }
 
+/********************************************************************************************
 
+>	void Tool_v1::RenderRulerBlobs(RulerBase* pRuler, UserRect& UpdateRect, BOOL IsBackground)
 
+	Author:		Martin Wuerthner <xara@xxxxxxxxxxxxxxx>
+	Created:	07/07/06
+	Inputs:		pRuler - the ruler that is currently being redrawn
+				UpdateRect - the rectangle to be updated in user coordinates (with the tool
+							 origin applied)
+				IsBackground - whether this is the call before drawing the main blobs
+							   or the call after rendering the main blobs
+	Purpose:	Gives the current tool the chance to render additional blobs on the ruler
+				Is called twice - once before the standard ruler graphics are rendered
+				(to allow additional background to be drawn) and once afterwards
 
+********************************************************************************************/
+
+void Tool_v1::RenderRulerBlobs(RulerBase* pRuler, UserRect& UpdateRect, BOOL IsBackground)
+{
+	// 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,
@@ -1555,7 +1578,8 @@
 									  )
 	Author:		Phil_Martin (Xara Group Ltd) <camelotdev@xxxxxxxx>
 	Created:	30/Jun/2006
-	Inputs:		PointerPos	- SpreadCoord of click within spread
+	Inputs:		nFlags      - synthesized mouse event flags (to be passed through to StartToolDrag)
+				PointerPos	- user coordinates of click on ruler (relative to origin set by tool)
 				Click		- Type of click enum
 				Mods		- Modifier flags struct
 				pSpread		- pointer to spread upon which click occurred
@@ -1568,7 +1592,8 @@
 
 ********************************************************************************************/
 
-BOOL Tool_v1::OnRulerClick( DocCoord PointerPos,
+BOOL Tool_v1::OnRulerClick( UINT32 nFlags,
+							UserCoord PointerPos,
 							ClickType Click,
 							ClickModifiers Mods,
 							Spread* pSpread,