Привязка курсора мыши к строке в пользовательском элементе управления Delphi - PullRequest
0 голосов
/ 17 февраля 2012

Мне интересно, как я могу добиться горизонтальной (или вертикальной) привязки курсора мыши к линии. Например, на временной шкале Facebook, когда вы наводите курсор мыши на линию вниз по центру, она привязывает курсор к центру. Приведение мыши к линии также приводит к ее привязке.

Я бы хотел обернуть это внутри одного пользовательского элемента управления, а не элементов формы. Там будет вертикальная или горизонтальная линия, и он должен привязать курсор мыши к нему, когда он приблизится. Я буду добавлять события, которые возвращают позицию строки, по которой щелкнули. Этот элемент управления также будет иметь полосу прокрутки, вертикальную или горизонтальную, параллельную этой линии, и обе полосы прокрутки никогда не будут отображаться одновременно. Существует главное свойство, отображать ли эту строку по вертикали или по горизонтали .

Мышь на самом деле не должна перемещать позицию, а просто отображение курсора должно быть каким-то образом настроено на показ в центре этой строки, в то время как фактическая позиция X (или Y) никогда не меняется. Я не хочу перемещать курсор, я хочу отображать курсор в центре этой строки, если он приближается. Когда курсор находится в этой привязанной позиции, он будет отображать другой пользовательский курсор вместо стандартной (или стандартной) стрелки.

Все, что мне нужно знать, - это как обрабатывать в этом элементе управления указатель мыши, находящийся в непосредственной близости от этой линии, и настраивать отображение курсора, чтобы он находился в центре этой линии.

Ответы [ 2 ]

5 голосов
/ 17 февраля 2012

Привязка требует, чтобы вы щелкнули что-то .

  • в AutoCAD «курсор» - это горизонтальная и вертикальная линия, пересекающаяся с «курсором»
  • Photoshop использует мышь Windows, но привязывает эффект к рекомендациям
  • Facebook привязывает небольшой + знак к месту на временной шкале

Вам необходимо отслеживать положение мыши (т. Е. OnMouseMove), и, если курсор находится "достаточно близко", вы можете решить, что делать.

Вот небольшая примерная программа, где у меня есть воображаемая вертикальная линия в 150 пикселей слева. Если я подойду достаточно близко к этой линии, появится маленький Facebook + :

enter image description here

const
    centerLine = 150; //"line" is at 150px from the left
    tolerance = 15; //15px on either size is about good.

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
    if IsMouseNearLine(x, y) then
    begin
        //We're on the centerline-ish. React by...
        //...changing the cursor to a <->
        Self.Cursor := crSizeWE;

        //and maybe let's put a "+" there, like Facebook
        if (FPlusLabel = nil) then
        begin
            FPlusLabel := TLabel.Create(Self);
            FPlusLabel.Parent := Self;
            FPlusLabel.Caption := '+';
            FPlusLabel.Alignment := taCenter;
            FPlusLabel.Font.Color := $00996600; //Windows UX "Main Instruction" color
            FPlusLabel.Font.Style := FPlusLabel.Font.Style + [fsBold];
        end;

        FPlusLabel.Left := centerLine-(FPlusLabel.Width div 2);
        FPlusLabel.Top := Y-(FPlusLabel.Height div 2);
        FPlusLabel.Visible := True;
    end
    else
    begin
        Self.Cursor := crDefault;
        if Assigned(FPlusLabel) then
            FPlusLabel.Visible := False;
    end;
end;

function TForm1.IsMouseNearLine(X, Y: Integer): Boolean;
begin
    if (x >= (centerLine-tolerance)) and (x <= (centerLine+tolerance)) then
    begin
        //we're close-ish to the line
        Result := true;
    end
    else
        Result := False;
end;

Вещи начинают волноваться, когда у вас есть другие элементы управления, каждый из которых должен играть вместе с сообщениями MouseMove. Но это не слишком плохо, если вы перенаправите их все в один обработчик; выполнение клиента с экрана на форму клиента перед вами.

Примечание : любой код публикуется в открытом доступе. Указание авторства не требуется.

1 голос
/ 20 февраля 2012

Самый простой подход, который я вижу, это создать элемент управления TPaintBox с его собственным свойством Cursor, чтобы вы скрывали встроенный курсор Windows и владелец рисовал символ «+» в его «привязанном» месте.1002 * Указатель мыши никогда не перемещается, но он «заменяется» изображением курсора, нарисованным владельцем, когда настоящий указатель мыши находится внутри границ элемента управления TPaintBox.

...