// $Revision: 1.4 $ // Copyright (C) 1994-1995 Taligent, Inc. All rights reserved. #ifndef TaligentSamples_TEXTTOOLSAMPLE #include "TextToolSample.h" #endif #ifndef Taligent_BUNDLES #include #endif #ifndef Taligent_GRAPHICS #include #endif #ifndef Taligent_INSERTIONOFFSET #include #endif #ifndef Taligent_LINELAYOUTSTYLES #include #endif #ifndef Taligent_TEXTSELECTION #include #endif #ifndef Taligent_TEXTMODEL #include #endif // All objects allocated in this code are allocated in the default heap. // TTextTool applies a TCommandOn to the text selected // during tool interaction. MCollectibleDefinitionsMacro(TSampleTextTool, kOriginalVersion); TTypeDescription gTargetType(StaticTypeInfo(TTextToolInteractionTarget)); TSampleTextTool::TSampleTextTool() : TSimpleMouseTool(gTargetType), fCommand(NIL), fCursorGraphic(NIL), fPaletteGraphic(NIL), fPaletteText(NIL) { } TSampleTextTool::TSampleTextTool( TCommandOn* commandToAdopt, MGraphic* cursorGraphicToAdopt, MGraphic* paletteGraphicToAdopt, TText* paletteTextToAdopt) : TSimpleMouseTool(gTargetType), fCommand(commandToAdopt), fCursorGraphic(cursorGraphicToAdopt), fPaletteGraphic(paletteGraphicToAdopt), fPaletteText(paletteTextToAdopt) { Assertion(commandToAdopt != NIL); } TSampleTextTool::TSampleTextTool(const TSampleTextTool& source) : TSimpleMouseTool(source), fCommand(NIL), fCursorGraphic(NIL), fPaletteGraphic(NIL), fPaletteText(NIL) { InternalCopy(source); } TSampleTextTool::~TSampleTextTool() { InternalDelete(); } TSampleTextTool& TSampleTextTool::operator=(const TSampleTextTool& source) { if (&source != this) { TTool::operator=(source); InternalDelete(); InternalCopy(source); } return *this; } // Do not delete text if we don't supply any, so the caller can provide default text. void TSampleTextTool::GetPaletteText(TText& text) const { if (fPaletteText) { text.Replace(*fPaletteText); } } MGraphic* TSampleTextTool::CreatePaletteGraphic() const { return ::CopyPointer(fPaletteGraphic); } MGraphic* TSampleTextTool::CreateCursorGraphic() const { return ::CopyPointer(fCursorGraphic); } TToolInteractor* TSampleTextTool::CreateInteractor(MToolTarget* adoptTarget) const // mutable (maybe) { // Check to make sure we weren't improperly constructed. Assertion(fCommand != NIL); TSampleTextToolInteractor* interactor = NIL; TTextToolInteractionTarget *target = NIL; ::DynamicCastTo(target, adoptTarget); if (target) { // Cast away const. TSampleTextTool* nonConstThis = (TSampleTextTool*)this; interactor = new TSampleTextToolInteractor( nonConstThis->GetToolHandler(), target, ::CopyPointer(fCommand)); interactor->SetCoordinateView(nonConstThis->GetToolView()); } else { delete adoptTarget; } return interactor; } TStream& TSampleTextTool::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TTool::operator>>=(toStream); ::Flatten(fCommand, toStream); ::Flatten(fCursorGraphic, toStream); ::Flatten(fPaletteGraphic, toStream); ::Flatten(fPaletteText, toStream); return toStream; } TStream& TSampleTextTool::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TTool::operator<<=(fromStream); InternalDelete(); ::Resurrect(fCommand , fromStream); ::Resurrect(fCursorGraphic, fromStream); ::Resurrect(fPaletteGraphic, fromStream); ::Resurrect(fPaletteText, fromStream); return fromStream; } MGraphic* TSampleTextTool::CreateHighlighterGraphic(const TRGBColor& fillColor) { const TGPoint points[] = { TGPoint( 0,-4), TGPoint( 0, 4), TGPoint( 4, 8), TGPoint( 3,10), TGPoint( 3,12), TGPoint( 4,14), TGPoint( 7,17), TGPoint(17, 7), TGPoint(14, 4), TGPoint(12, 3), TGPoint(10, 3), TGPoint( 8, 4) }; const int numPoints = sizeof(points)/sizeof(TGPoint&); TGPolygon polygon(numPoints); for (int i = 0; i < numPoints; i++) { polygon.SetPoint(i, points[i]); } const TRGBColor frameColor(0,0,0); const GCoordinate penThickness = 1.0; TGrafBundle* bundle = new TGrafBundle(fillColor, frameColor); bundle->AdoptFramePen(new TSolidPen(penThickness, TPen::kOutsetFrame)); return new TPolygon(polygon, bundle); } MGraphic* TSampleTextTool::CreateEraserGraphic(const TRGBColor& fillColor) { TGPolygon eraserTip(4); eraserTip.SetPoint(0, TGPoint( 0,-4)); eraserTip.SetPoint(1, TGPoint(11,-8)); eraserTip.SetPoint(2, TGPoint(11, 8)); eraserTip.SetPoint(3, TGPoint( 0, 4)); TGPolygon eraserBody(6); eraserBody.SetPoint(0, TGPoint(11,-6)); eraserBody.SetPoint(1, TGPoint(17,-6)); eraserBody.SetPoint(2, TGPoint(18,-4)); eraserBody.SetPoint(3, TGPoint(18, 4)); eraserBody.SetPoint(4, TGPoint(17, 6)); eraserBody.SetPoint(5, TGPoint(11, 6)); const TRGBColor frameColor(0,0,0); const GCoordinate penThickness = 1.0; TGrafBundle* tipBundle = new TGrafBundle(fillColor, frameColor); tipBundle->AdoptFramePen(new TSolidPen(penThickness, TPen::kOutsetFrame)); TGrafBundle* bodyBundle = new TGrafBundle(fillColor, frameColor); bodyBundle->AdoptFramePen(new TSolidPen(penThickness, TPen::kInsetFrame)); TGraphicGroup* eraser = new TGraphicGroup; eraser->AdoptLast(new TPolygon(eraserTip, tipBundle)); eraser->AdoptLast(new TPolygon(eraserBody, bodyBundle)); return eraser; } void TSampleTextTool::InternalCopy(const TSampleTextTool& source) { fCommand = ::CopyPointer(source.fCommand); fCursorGraphic = ::CopyPointer(source.fCursorGraphic); fPaletteGraphic = ::CopyPointer(source.fPaletteGraphic); fPaletteText = ::CopyPointer(source.fPaletteText); } void TSampleTextTool::InternalDelete() { delete fCommand; fCommand = NIL; delete fCursorGraphic; fCursorGraphic = NIL; delete fPaletteGraphic; fPaletteGraphic = NIL; delete fPaletteText; fPaletteText = NIL; } // ======== VersionDefinitionsMacro(TSampleTextToolInteractor, 0); TSampleTextToolInteractor::TSampleTextToolInteractor( MToolHandler* handlerAlias, TTextToolInteractionTarget* targetToAdopt, TCommandOn* commandToAdopt) : TToolInteractor(handlerAlias), MMouseEventHandler(), fSelection(NIL), fTarget(targetToAdopt), fCommand(commandToAdopt) { Assertion(handlerAlias != NIL); Assertion(targetToAdopt != NIL); Assertion(commandToAdopt != NIL); } TSampleTextToolInteractor::TSampleTextToolInteractor(const TSampleTextToolInteractor& source) : TToolInteractor(source), MMouseEventHandler(source), fSelection(NIL), fTarget(NIL), fCommand(NIL) { fTarget = ::CopyPointer(source.fTarget); fCommand = ::CopyPointer(source.fCommand); } TSampleTextToolInteractor::~TSampleTextToolInteractor() { delete fSelection; delete fTarget; delete fCommand; } bool TSampleTextToolInteractor::MouseDown(TMouseDownEvent& mouseDown) { StartMouseMovedEvents(*mouseDown.GetMouseInputDevice()); TGPoint position = mouseDown.GetEventPosition(); fSelection = fTarget->CreateTextSelection(position, fAnchor); fTarget->AdoptTextSelection(::CopyPointer(fSelection)); return true; } bool TSampleTextToolInteractor::MouseMoved(TMouseMovedEvent& mouseMove) { TGPoint position = mouseMove.GetEventPosition(); fTarget->ExtendTextSelection(position, fAnchor, *fSelection); fTarget->AdoptTextSelection(::CopyPointer(fSelection)); return true; } // Mouse position is the same as last mouse down or moved, so no need to // recompute the selection. // Establish the final selection as an insertion point at the mouse up // location. // Execute command on the full selection. A binding is used so it can // be saved in a command history. The command and selection are adopted, // so release ownership. bool TSampleTextToolInteractor::MouseUp(TMouseUpEvent& mouseUp) { StopMouseMovedEvents(); MTextSelection* selection = ::CopyPointer(fSelection); TTextRange range; selection->GetFirstRange(range); TTextOffset finalOffset = range.GetEnd(); if (finalOffset == fAnchor) { finalOffset = range.GetBegin(); } selection->SetInsertionOffset(TInsertionOffset(finalOffset)); fTarget->AdoptTextSelection(selection); TTextRepresentationWriteEntry entry(fSelection); TToolCommandBindingTo* binding = new TToolCommandBindingTo(fCommand, fSelection); AdoptAndDo(binding); fCommand = NIL; fSelection = NIL; SetDone(true); return true; }