Skip to content

Commit 7a78b58

Browse files
FIX: Select Glitch
1 parent 911c3dd commit 7a78b58

File tree

6 files changed

+78
-36
lines changed

6 files changed

+78
-36
lines changed

miniprojects/Bridge_Builder/ueventer.pas

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(******************************************************************************)
22
(* Eventer 09.05.2019 *)
33
(* *)
4-
(* Version : 0.05 *)
4+
(* Version : 0.06 *)
55
(* *)
66
(* Author : Uwe Schächterle (Corpsman) *)
77
(* *)
@@ -26,6 +26,7 @@
2626
(* 0.03 - improve .click detection *)
2727
(* 0.04 - MouseEnter / MouseLeave *)
2828
(* 0.05 - Owner property public *)
29+
(* 0.06 - Click event only, if mouse down was also on element *)
2930
(* *)
3031
(* Known Bugs : none *)
3132
(* *)
@@ -198,7 +199,7 @@
198199
fOnMouseDownCapture: TMouseEvent;
199200
fOnMouseMoveCapture: TMouseMoveEvent;
200201
fOnMouseUpCapture: TMouseEvent;
201-
202+
fTransformedMouseDownPos: TPoint;
202203
{$IFDEF KeyEvents}
203204
fOnKeyDownCapture: TKeyEvent;
204205
fOnKeyUpCapture: TKeyEvent;
@@ -304,7 +305,13 @@
304305
End;
305306
For i := 0 To high(fEventer) Do Begin
306307
If i > high(fEventer) Then break; // Da im Event das Eventer element auch freigegeben werden darf, braucht es dieses if
307-
If PointInRect(point(x, y), fEventer[i].ClientRect) And fEventer[i].fVisible And fEventer[i].fEnabled Then Begin
308+
If
309+
// Das Element wurde im MouseDown bereits ausgewählt
310+
PointInRect(point(fTransformedMouseDownPos.x, fTransformedMouseDownPos.y), fEventer[i].ClientRect)
311+
// Das Element ist immer noch ausgewählt
312+
And PointInRect(point(x, y), fEventer[i].ClientRect)
313+
And fEventer[i].fVisible
314+
And fEventer[i].fEnabled Then Begin
308315
handled := true;
309316
If fMouseDownEventer = fEventer[i] Then fMouseDownEventer := Nil;
310317
fEventer[i].MouseUp(button, shift, x - fEventer[i].Left, y - fEventer[i].Top);
@@ -343,6 +350,7 @@
343350
x := p.x;
344351
y := p.y;
345352
End;
353+
fTransformedMouseDownPos := point(x, y);
346354
For i := 0 To high(fEventer) Do Begin
347355
fEventer[i].FFocus := false;
348356
End;

miniprojects/Imageinspector/ueventer.pas

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(******************************************************************************)
22
(* Eventer 09.05.2019 *)
33
(* *)
4-
(* Version : 0.05 *)
4+
(* Version : 0.06 *)
55
(* *)
66
(* Author : Uwe Schächterle (Corpsman) *)
77
(* *)
@@ -26,6 +26,7 @@
2626
(* 0.03 - improve .click detection *)
2727
(* 0.04 - MouseEnter / MouseLeave *)
2828
(* 0.05 - Owner property public *)
29+
(* 0.06 - Click event only, if mouse down was also on element *)
2930
(* *)
3031
(* Known Bugs : none *)
3132
(* *)
@@ -198,7 +199,7 @@
198199
fOnMouseDownCapture: TMouseEvent;
199200
fOnMouseMoveCapture: TMouseMoveEvent;
200201
fOnMouseUpCapture: TMouseEvent;
201-
202+
fTransformedMouseDownPos: TPoint;
202203
{$IFDEF KeyEvents}
203204
fOnKeyDownCapture: TKeyEvent;
204205
fOnKeyUpCapture: TKeyEvent;
@@ -304,7 +305,13 @@
304305
End;
305306
For i := 0 To high(fEventer) Do Begin
306307
If i > high(fEventer) Then break; // Da im Event das Eventer element auch freigegeben werden darf, braucht es dieses if
307-
If PointInRect(point(x, y), fEventer[i].ClientRect) And fEventer[i].fVisible And fEventer[i].fEnabled Then Begin
308+
If
309+
// Das Element wurde im MouseDown bereits ausgewählt
310+
PointInRect(point(fTransformedMouseDownPos.x, fTransformedMouseDownPos.y), fEventer[i].ClientRect)
311+
// Das Element ist immer noch ausgewählt
312+
And PointInRect(point(x, y), fEventer[i].ClientRect)
313+
And fEventer[i].fVisible
314+
And fEventer[i].fEnabled Then Begin
308315
handled := true;
309316
If fMouseDownEventer = fEventer[i] Then fMouseDownEventer := Nil;
310317
fEventer[i].MouseUp(button, shift, x - fEventer[i].Left, y - fEventer[i].Top);
@@ -343,6 +350,7 @@
343350
x := p.x;
344351
y := p.y;
345352
End;
353+
fTransformedMouseDownPos := point(x, y);
346354
For i := 0 To high(fEventer) Do Begin
347355
fEventer[i].FFocus := false;
348356
End;

miniprojects/Imageshop/ueventer.pas

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(******************************************************************************)
22
(* Eventer 09.05.2019 *)
33
(* *)
4-
(* Version : 0.05 *)
4+
(* Version : 0.06 *)
55
(* *)
66
(* Author : Uwe Schächterle (Corpsman) *)
77
(* *)
@@ -26,6 +26,7 @@
2626
(* 0.03 - improve .click detection *)
2727
(* 0.04 - MouseEnter / MouseLeave *)
2828
(* 0.05 - Owner property public *)
29+
(* 0.06 - Click event only, if mouse down was also on element *)
2930
(* *)
3031
(* Known Bugs : none *)
3132
(* *)
@@ -198,7 +199,7 @@
198199
fOnMouseDownCapture: TMouseEvent;
199200
fOnMouseMoveCapture: TMouseMoveEvent;
200201
fOnMouseUpCapture: TMouseEvent;
201-
202+
fTransformedMouseDownPos: TPoint;
202203
{$IFDEF KeyEvents}
203204
fOnKeyDownCapture: TKeyEvent;
204205
fOnKeyUpCapture: TKeyEvent;
@@ -304,7 +305,13 @@
304305
End;
305306
For i := 0 To high(fEventer) Do Begin
306307
If i > high(fEventer) Then break; // Da im Event das Eventer element auch freigegeben werden darf, braucht es dieses if
307-
If PointInRect(point(x, y), fEventer[i].ClientRect) And fEventer[i].fVisible And fEventer[i].fEnabled Then Begin
308+
If
309+
// Das Element wurde im MouseDown bereits ausgewählt
310+
PointInRect(point(fTransformedMouseDownPos.x, fTransformedMouseDownPos.y), fEventer[i].ClientRect)
311+
// Das Element ist immer noch ausgewählt
312+
And PointInRect(point(x, y), fEventer[i].ClientRect)
313+
And fEventer[i].fVisible
314+
And fEventer[i].fEnabled Then Begin
308315
handled := true;
309316
If fMouseDownEventer = fEventer[i] Then fMouseDownEventer := Nil;
310317
fEventer[i].MouseUp(button, shift, x - fEventer[i].Left, y - fEventer[i].Top);
@@ -343,6 +350,7 @@
343350
x := p.x;
344351
y := p.y;
345352
End;
353+
fTransformedMouseDownPos := point(x, y);
346354
For i := 0 To high(fEventer) Do Begin
347355
fEventer[i].FFocus := false;
348356
End;

miniprojects/PixelEditor/ueventer.pas

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(******************************************************************************)
22
(* Eventer 09.05.2019 *)
33
(* *)
4-
(* Version : 0.05 *)
4+
(* Version : 0.06 *)
55
(* *)
66
(* Author : Uwe Schächterle (Corpsman) *)
77
(* *)
@@ -26,6 +26,7 @@
2626
(* 0.03 - improve .click detection *)
2727
(* 0.04 - MouseEnter / MouseLeave *)
2828
(* 0.05 - Owner property public *)
29+
(* 0.06 - Click event only, if mouse down was also on element *)
2930
(* *)
3031
(* Known Bugs : none *)
3132
(* *)
@@ -198,7 +199,7 @@
198199
fOnMouseDownCapture: TMouseEvent;
199200
fOnMouseMoveCapture: TMouseMoveEvent;
200201
fOnMouseUpCapture: TMouseEvent;
201-
202+
fTransformedMouseDownPos: TPoint;
202203
{$IFDEF KeyEvents}
203204
fOnKeyDownCapture: TKeyEvent;
204205
fOnKeyUpCapture: TKeyEvent;
@@ -304,7 +305,13 @@
304305
End;
305306
For i := 0 To high(fEventer) Do Begin
306307
If i > high(fEventer) Then break; // Da im Event das Eventer element auch freigegeben werden darf, braucht es dieses if
307-
If PointInRect(point(x, y), fEventer[i].ClientRect) And fEventer[i].fVisible And fEventer[i].fEnabled Then Begin
308+
If
309+
// Das Element wurde im MouseDown bereits ausgewählt
310+
PointInRect(point(fTransformedMouseDownPos.x, fTransformedMouseDownPos.y), fEventer[i].ClientRect)
311+
// Das Element ist immer noch ausgewählt
312+
And PointInRect(point(x, y), fEventer[i].ClientRect)
313+
And fEventer[i].fVisible
314+
And fEventer[i].fEnabled Then Begin
308315
handled := true;
309316
If fMouseDownEventer = fEventer[i] Then fMouseDownEventer := Nil;
310317
fEventer[i].MouseUp(button, shift, x - fEventer[i].Left, y - fEventer[i].Top);
@@ -343,6 +350,7 @@
343350
x := p.x;
344351
y := p.y;
345352
End;
353+
fTransformedMouseDownPos := point(x, y);
346354
For i := 0 To high(fEventer) Do Begin
347355
fEventer[i].FFocus := false;
348356
End;

miniprojects/PixelEditor/upixeleditor.pas

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
* FIX: Memleak on STRG+C
7070
* ADD: Cleanup STRG+C / STRG+V Code
7171
* 0.10 - ADD: Feature Request #7 Add Background Image (via double right click)
72+
* ADD: improve UI for Select subimage
7273
*
7374
* Known Bugs:
7475
* - Ellipsen kleiner 4x4 Pixel werden nicht erzeugt
@@ -243,7 +244,7 @@
243244
Function getChanged: Boolean;
244245

245246
Procedure LoadColorDialogColor(Sender: TObject);
246-
Function CursorToPixel(x, y: integer): TPoint;
247+
Function CursorToPixel(x, y: integer; ClampToImage: Boolean): TPoint;
247248
Function CursorIsInImageWindow: Boolean;
248249
Procedure SetLeftColor(Const c: TOpenGL_ColorBox);
249250
Procedure SetRightColor(Const c: TRGBA);
@@ -655,7 +656,7 @@
655656
If fCriticalError <> '' Then exit;
656657
If ColorPicDialog.Visible Then exit; // ColorPicDialog Modal emulieren ;)
657658
fScrollInfo.ScrollPos := point(x, y);
658-
fCursor.Compact.PixelPos := CursorToPixel(x, y);
659+
fCursor.Compact.PixelPos := CursorToPixel(x, y, true);
659660
fCursor.LastMovePos := fCursor.Compact.PixelPos;
660661
fCursor.Pos := point(x, y);
661662
fCursor.PixelDownPos := fCursor.Compact.PixelPos;
@@ -746,7 +747,8 @@
746747
Begin
747748
If fCriticalError <> '' Then exit;
748749
If ColorPicDialog.Visible Then exit; // ColorPicDialog Modal emulieren ;)
749-
fCursor.Compact.PixelPos := CursorToPixel(x, y);
750+
fCursor.Compact.PixelPos := CursorToPixel(x, y, true);
751+
fCursor.UnClampedMousePos := CursorToPixel(x, y, false);
750752
fCursor.Pos := point(x, y);
751753
If ssLeft In shift Then Begin
752754
If (CursorIsInImageWindow()) And (Not ColorPicDialog.Visible) Then Begin
@@ -798,26 +800,28 @@
798800
ColorPicDialog.Visible := false;
799801
exit;
800802
End;
801-
fCursor.Compact.PixelPos := CursorToPixel(x, y);
803+
fCursor.Compact.PixelPos := CursorToPixel(x, y, true);
802804
fCursor.Pos := Point(x, y);
803-
If (button = mbLeft) And (CursorIsInImageWindow()) And (Not ColorPicDialog.Visible) Then Begin
805+
If (button = mbLeft) And (Not ColorPicDialog.Visible) Then Begin
804806
Case fCursor.Tool Of
805807
tEraser, tPen, tMirror,
806808
tLine, tEllipse, tBucket,
807809
tRectangle: Begin
808-
fImage.BeginUpdate;
809-
CursorToPixelOperation(@SetImagePixelByCursor);
810-
fImage.EndUpdate;
811-
fundo.PushRecording;
810+
If (CursorIsInImageWindow()) Then Begin
811+
fImage.BeginUpdate;
812+
CursorToPixelOperation(@SetImagePixelByCursor);
813+
fImage.EndUpdate;
814+
fundo.PushRecording;
815+
End;
812816
End;
813-
tPipette: UnselectPipette;
817+
tPipette: If (CursorIsInImageWindow()) Then UnselectPipette;
814818
TSelect: Begin
815819
If Not fCursor.Select.aSet Then Begin
816820
If fCursor.LeftMouseButton Then Begin
817-
fCursor.Select.tl.x := min(fCursor.PixelDownPos.X, fCursor.Compact.PixelPos.X);
818-
fCursor.Select.tl.Y := min(fCursor.PixelDownPos.Y, fCursor.Compact.PixelPos.Y);
819-
fCursor.Select.br.x := max(fCursor.PixelDownPos.X, fCursor.Compact.PixelPos.X);
820-
fCursor.Select.br.Y := max(fCursor.PixelDownPos.Y, fCursor.Compact.PixelPos.Y);
821+
fCursor.Select.tl.x := max(0, min(fCursor.PixelDownPos.X, fCursor.UnClampedMousePos.X));
822+
fCursor.Select.tl.Y := max(0, min(fCursor.PixelDownPos.Y, fCursor.UnClampedMousePos.Y));
823+
fCursor.Select.br.x := min(fImage.Width - 1, max(fCursor.PixelDownPos.X, fCursor.UnClampedMousePos.X));
824+
fCursor.Select.br.Y := min(fImage.Height - 1, max(fCursor.PixelDownPos.Y, fCursor.UnClampedMousePos.Y));
821825
// Wenn der User nur auf einen Pixel Klickt, dann passiert nix
822826
If Not (((fCursor.Select.br.x - fCursor.Select.tl.X) = 0)
823827
And ((fCursor.Select.br.Y - fCursor.Select.tl.Y) = 0)) Then Begin
@@ -1575,10 +1579,10 @@
15751579
valid := false;
15761580
If (fCursor.LeftMouseButton) Then Begin
15771581
// Der Auswahl Rahmen wird gerade gezogen
1578-
tl.x := min(fCursor.PixelDownPos.X, fCursor.Compact.PixelPos.X);
1579-
tl.Y := min(fCursor.PixelDownPos.Y, fCursor.Compact.PixelPos.Y);
1580-
br.x := max(fCursor.PixelDownPos.X, fCursor.Compact.PixelPos.X);
1581-
br.Y := max(fCursor.PixelDownPos.Y, fCursor.Compact.PixelPos.Y);
1582+
tl.x := max(0, min(fCursor.PixelDownPos.X, fCursor.UnClampedMousePos.X));
1583+
tl.Y := max(0, min(fCursor.PixelDownPos.Y, fCursor.UnClampedMousePos.Y));
1584+
br.x := min(fImage.Width - 1, max(fCursor.PixelDownPos.X, fCursor.UnClampedMousePos.X));
1585+
br.Y := min(fImage.Height - 1, max(fCursor.PixelDownPos.Y, fCursor.UnClampedMousePos.Y));
15821586
valid := (tl.x <> -1);
15831587
End;
15841588
If fCursor.Select.aSet Then Begin
@@ -1679,7 +1683,7 @@
16791683
p1, p2: TPoint;
16801684
Begin
16811685
// Store the old position
1682-
p1 := CursorToPixel(fCursor.Pos.X, fCursor.Pos.Y);
1686+
p1 := CursorToPixel(fCursor.Pos.X, fCursor.Pos.Y, true);
16831687
// Do the Zoom
16841688
If ZoomIn Then Begin
16851689
For i := 0 To high(ZoomLevels) Do Begin
@@ -1698,18 +1702,18 @@
16981702
End;
16991703
End;
17001704
// Calc the new "wrong" position
1701-
p2 := CursorToPixel(fCursor.Pos.X, fCursor.Pos.y);
1705+
p2 := CursorToPixel(fCursor.Pos.X, fCursor.Pos.y, true);
17021706
// "Scroll" so that the new position is the old one ;)
17031707
fScrollInfo.GlobalXOffset := fScrollInfo.GlobalXOffset + (p1.x - p2.x) * fZoom Div 100 * ScreenWidth Div FOwner.Width;
17041708
fScrollInfo.GlobalyOffset := fScrollInfo.GlobalyOffset + (p1.Y - p2.Y) * fZoom Div 100 * ScreenHeight Div FOwner.Height;
17051709
// Let the scrollbars do their constraint thing
17061710
// Nachziehen des Cursors sonst springt der beim Zoomen
1707-
fCursor.compact.PixelPos := CursorToPixel(fCursor.Pos.x, fCursor.Pos.y);
1711+
fCursor.compact.PixelPos := CursorToPixel(fCursor.Pos.x, fCursor.Pos.y, true);
17081712
CheckScrollBorders();
17091713
UpdateInfoLabel;
17101714
End;
17111715

1712-
Function TPixelEditor.CursorToPixel(x, y: integer): TPoint;
1716+
Function TPixelEditor.CursorToPixel(x, y: integer; ClampToImage: Boolean): TPoint;
17131717
Var
17141718
rx, ry: Single;
17151719
riy, rix: Integer;
@@ -1732,8 +1736,13 @@
17321736
// 5. Limitieren auf die Image Größe
17331737
rix := round(rx);
17341738
riy := round(ry);
1735-
If (rix >= 0) And (rix < fImage.Width) And
1736-
(riy >= 0) And (riy < fImage.Height) Then Begin
1739+
If ClampToImage Then Begin
1740+
If (rix >= 0) And (rix < fImage.Width) And
1741+
(riy >= 0) And (riy < fImage.Height) Then Begin
1742+
result := point(rix, riy);
1743+
End;
1744+
End
1745+
Else Begin
17371746
result := point(rix, riy);
17381747
End;
17391748
End;

miniprojects/PixelEditor/upixeleditor_types.pas

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148

149149
TCursor = Record
150150
Compact: TCompactCursor;
151+
UnClampedMousePos: TPoint; // Die Aktuelle Mausposition im Bild kontext, ohne Clamping auf die Tatsächliche Bild größe!
151152
LastMovePos: TPoint; // die letzte Pixelpos von MouseMove
152153
// Alles was der Cursor noch mehr braucht
153154
LeftColor: TOpenGL_ColorBox;

0 commit comments

Comments
 (0)