2525// THE SOFTWARE.
2626
2727using System ;
28+ using System . Collections . Generic ;
2829using Gdk ;
2930using Pinta . Core ;
3031
@@ -39,11 +40,15 @@ public sealed class CloneStampTool : BaseBrushTool
3940
4041 private readonly SystemManager system_manager ;
4142 private readonly IWorkspaceService workspace ;
43+ private readonly BrushHandle handle ;
44+ private bool move_origin_handle = true ;
4245 public CloneStampTool ( IServiceProvider services ) : base ( services )
4346 {
4447 system_manager = services . GetService < SystemManager > ( ) ;
4548 workspace = services . GetService < IWorkspaceService > ( ) ;
4649
50+ handle = new BrushHandle ( workspace ) ;
51+
4752 // Update cursor on zoom
4853 workspace . ViewSizeChanged += ( _ , _ ) => {
4954 if ( IsActiveTool ( ) ) {
@@ -59,6 +64,7 @@ public CloneStampTool (IServiceProvider services) : base (services)
5964 public override Gdk . Key ShortcutKey => new ( Gdk . Constants . KEY_L ) ;
6065 public override int Priority => 47 ;
6166 protected override bool ShowAntialiasingButton => true ;
67+ public override IEnumerable < IToolHandle > Handles => [ handle ] ;
6268
6369 public override Cursor DefaultCursor {
6470 get {
@@ -94,17 +100,23 @@ protected override void OnMouseDown (Document document, ToolMouseEventArgs e)
94100 } else {
95101 origin = e . Point ;
96102 offset = null ;
103+ UpdateOriginHandle ( document , origin . Value . X , origin . Value . Y , false ) ;
97104 }
98105 }
99106
100107 protected override void OnMouseMove ( Document document , ToolMouseEventArgs e )
101108 {
102- if ( ! painting || ! offset . HasValue )
109+ if ( ! offset . HasValue )
103110 return ;
104111
105112 var x = e . Point . X ;
106113 var y = e . Point . Y ;
107114
115+ UpdateOriginHandle ( document , x - offset . Value . X , y - offset . Value . Y , true ) ;
116+
117+ if ( ! painting )
118+ return ;
119+
108120 if ( ! last_point . HasValue ) {
109121 last_point = e . Point ;
110122 return ;
@@ -134,6 +146,9 @@ protected override void OnMouseUp (Document document, ToolMouseEventArgs e)
134146 {
135147 painting = false ;
136148
149+ if ( e . IsControlPressed )
150+ handle . Active = true ;
151+
137152 using Cairo . Context g = new ( document . Layers . CurrentUserLayer . Surface ) ;
138153 g . SetSourceSurface ( document . Layers . ToolLayer . Surface , 0 , 0 ) ;
139154 g . Paint ( ) ;
@@ -152,6 +167,7 @@ protected override bool OnKeyDown (Document document, ToolKeyEventArgs e)
152167 {
153168 // Note that this WON'T work if user presses control key and THEN selects the tool!
154169 if ( e . Key . IsControlKey ( ) ) {
170+ move_origin_handle = false ;
155171 SetCursor ( Gdk . Cursor . NewFromTexture ( Resources . GetIcon ( "Cursor.CloneStampSetSource.png" ) , 16 , 26 , null ) ) ;
156172 }
157173
@@ -160,14 +176,25 @@ protected override bool OnKeyDown (Document document, ToolKeyEventArgs e)
160176
161177 protected override bool OnKeyUp ( Document document , ToolKeyEventArgs e )
162178 {
163- if ( e . Key . IsControlKey ( ) )
179+ if ( e . Key . IsControlKey ( ) ) {
180+ move_origin_handle = true ;
164181 SetCursor ( DefaultCursor ) ;
182+ }
165183
166184 return false ;
167185 }
168186
169187 protected override void OnDeactivated ( Document ? document , BaseTool ? newTool )
170188 {
171189 origin = null ;
190+ handle . Active = false ;
191+ }
192+
193+ private void UpdateOriginHandle ( Document document , int x , int y , bool move_event )
194+ {
195+ if ( move_origin_handle || ( ! move_event ) )
196+ handle . CanvasPosition = new ( x , y ) ;
197+ handle . BrushWidth = BrushWidth ;
198+ document . Workspace . Invalidate ( handle . InvalidateRect ) ;
172199 }
173200}
0 commit comments