Перейти к содержанию
Fire Monkey от А до Я
  • 0

Перетаскивание отрезка


SergeyIT

Вопрос

В известном видео

https://www.youtube.com/watch?v=ta_N6DSi0Xg

представлена техника перетаскивания графических объектов типа TRectangle, TEllipse.

Почему она не работает для тех же объектов, но созданных программным путем, скажем, для TLine?

Быть может есть ключевое свойство, связанное с Captured особенностями.

 

Ухищрения с координатами также мало помогают. В лучшем случае все выглядит как перемещение с эффектом стробоскопа - объект движется, но "мигает" по 2-4 позициям.

Изменено пользователем SergeyIT
Ссылка на комментарий

Рекомендуемые сообщения

  • 0

При динамическом создании объектов указываете свойства OnMouseDown, OnMouseMove и пр. из примера видео? Про мигания: какая платформа? Пример кода?

P.S. Мне нравятся Ваши вопросы - с интересом слежу... Но иногда кажется что Вы - первый раз за develop...

Ссылка на комментарий
  • 0

 

Но иногда кажется что Вы - первый раз за develop...

Да, так и есть...

Я работаю Unity 3D Platform Lead в одной из американских компаний, занимаюсь вопросами архитектуры и адаптации паттернов проектирования GOF к игровому контексту. Параллельно веду проект www.orlovsoft.com. C Object Pascal знаком 2 недели, до этого 10 лет работал на .NET.

В последнем разочаровался и знакомлюсь с тем, что сделала за эти годы Embarcadero, искренне радуясь...

 

События мыши одни и те же для объекта, помещенного на форму и для программно созданного объекта, поэтому вряд ли имеет смысл переписывать код из ролика и его вариации. Платформа: Windows 10 64 bit. Сомнения в возможно неустановленном некоем свойстве для программно созданного объекта. Вот код создания объекта:

line := TLine.Create(Self);
  line.StrokeThickness := 10;
  line.LineType := TLineType.Diagonal;
  line.Position := TPosition.Create(TPointF.Create(130, 130));
  line.RotationAngle := 90;
  line.HitTest := True;
  line.StrokeCap := TStrokeCap.Round;
  line.Width := 100;
  line.DragMode:= TDragMode.dmManual;
  line.EnableDragHighlight:= True;

  line.OnMouseDown := CallBackMouseDown;
  line.OnMouseMove := CallBackMouseMove;
  line.OnMouseUp := CallBackMouseUp;
  line.Parent := Self;

Вот и все.

Изменено пользователем SergeyIT
Ссылка на комментарий
  • 0

Математику в студию, по второй линии видно , есть подозрение что реализованный алгоритм неправильно работает.

 

по коду.

Добавить:

line.Parent := Self;

 

ещё совет:

  line                    := TLine.Create(Self);
  line.Parent             := Self;
  line.LineType           := TLineType.Top;
  line.Position.Point     := TPointF.Create(130, 130);
  line.RotationAngle      := 90;
  line.HitTest            := True;
  line.Width              := 100;
  line.Height             := 5;
  line.StrokeThickness    := 5;

поясню: при диагональном расположении появляется мнимый прямоугольник, при котором если мышь будет находится в нём, то линия будет подсвечиваться. Хотя курсор мыши не будет находиться над линией.

Изменено пользователем Alexander
Ссылка на комментарий
  • 0

Вот весь код, обработчики общие. Не уверен, что можно отправлять такие куски кода... Удалю по первому запросу. Сорри

unit MainForm;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,
  System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Objects,
  System.Generics.Collections, FMX.Controls.Presentation, FMX.StdCtrls,
  Helpers, FMX.Edit, FMX.TabControl;

type
  TForm1 = class(TForm)
    lblInfoX: TLabel;
    edtX: TEdit;
    lblInfoY: TLabel;
    edtY: TEdit;
    rctngTest1: TRectangle;
    edtPosX: TEdit;
    lblPosX: TLabel;
    lblPosY: TLabel;
    edtPosY: TEdit;
    lnTest2: TLine;
    procedure FormCreate(Sender: TObject);
  //private
    { Private declarations }
    procedure CallBackMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
    procedure CallBackMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Single);
    procedure CallBackMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
  // public
    { Public declarations }
    private
    var
  _xCoord, _yCoord: Single;

  isDragging: Boolean;
  end;

var
  Form1: TForm1;
implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
// Just test with any TShape
 var line: TEllipse;
begin
  line := TEllipse.Create(nil);
  line.StrokeThickness := 10;
  line.Position := TPosition.Create(TPointF.Create(130, 130));
  line.RotationAngle := 90;
  line.HitTest := True;
  line.StrokeCap := TStrokeCap.Round;
  line.Width := 100;
  line.DragMode:= TDragMode.dmManual;
  line.EnableDragHighlight:= True;

  line.OnMouseDown := CallBackMouseDown;
  line.OnMouseMove := CallBackMouseMove;
  line.OnMouseUp := CallBackMouseUp;
  line.Parent := Self;
end;

procedure TForm1.CallBackMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Single);
  var shape : TControl;
begin
  if (isDragging = True) and (ssLeft in Shift) then
  begin
  shape:= (Sender as TControl);
    edtX.Text:= (X).ToString;
    edtY.Text:= (Y).ToString;

    edtPosX.Text:= (shape.Position.X).ToString;
    edtPosY.Text:= (shape.Position.Y).ToString;

    shape.Position.X := shape.Position.X +  X - _xCoord;
    shape.Position.Y := shape.Position.Y +  Y - _yCoord;
  end;

end;

procedure TForm1.CallBackMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
var
  classInfo: UnicodeString;
  shape : TShape;
begin
  classInfo := Sender.ClassName;
  shape := Sender as TShape;
    _xCoord := X;
    _yCoord := Y;
    edtX.Text:= (X).ToString;
    edtY.Text:= (Y).ToString;

    edtPosX.Text:= (shape.Position.X).ToString;
    edtPosY.Text:= (shape.Position.Y).ToString;
    shape.Fill.Color:= $FF11313A;
    isDragging := True;
    shape.Root.Captured := shape;
  end;


procedure TForm1.CallBackMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
  var shape: TShape;
begin
  if (isDragging = True) then
  begin
  shape:= Sender as TShape;
    isDragging := False;
    shape.Fill.Color:= $FF2CC831;
    shape.Root.Captured := nil;
  end;

end;

end.

Ссылка на комментарий
  • 0

@Yaroslav Решение в LocalToAbsoluteVector? Искал подобное...

@Alexandr Ну, трансформации нужны, в общем случае. Думаю вопрос снимется по подробностям

http://fire-monkey.ru/topic/34-kak-sdelat-peremeschenie-kontrola-myshkoipaltc/

 

Спасибо всем! Извиняюсь - просмотрел.

Не очевидно, однако, на фоне "легкости" ролика :) Координаты то X, Y - в коллбеке локальные, в пределах Sender.

 

Да, все работает. С преобразованием координат.

Изменено пользователем SergeyIT
Ссылка на комментарий
Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...