Жестовое масштабирование и панорамирование в приложении Windows VCL

#zooming #c builder #gesture #vcl #pan

Вопрос:

Я пытаюсь увеличить и панорамировать изображение (время) с объектом (TShape) на нем в приложении Windows VCL, работающем на ПК «все в одном» с сенсорным дисплеем.

Я помещаю изображение на панель (TPanel), поэтому, когда я увеличиваю его, оно всегда остается внутри панели. Затем я накладываю фигуру (TShape) на изображение.

То, что я хотел бы получить, — это масштабирование и панорамирование изображения, и фигура должна масштабироваться и перемещаться вместе с изображением.

Я начал с примера Embarcadero «Мобильные фрагменты — интерактивные объекты — ImageZoom», и со следующим кодом мне удалось увеличить и переместить изображение двумя пальцами:

 void __fastcall TForm1::Image1Gesture(TObject *Sender, const TGestureEventInfo amp;EventInfo,  bool amp;Handled)  {

TPointF LImageCenter;
double expance;
TPointF movement;

try {

    if (EventInfo.GestureID == static_cast<short>(Vcl::Controls::igiZoom)) {
        if (!EventInfo.Flags.Contains(TInteractiveGestureFlag::gfBegin) amp;amp;
                !EventInfo.Flags.Contains(TInteractiveGestureFlag::gfEnd)) {
            // zoom the image
            TImage * LImage = dynamic_cast<TImage*>(Image1);
            LImageCenter.x = LImage->Left   (LImage->Width / 2);
            LImageCenter.y = LImage->Top   (LImage->Height / 2);
            expance = EventInfo.Distance - FLastDistance;
            if (((LImage->Width   (expance * AR))> MIN_DIM) amp;amp;
                    ((LImage->Height   (expance))> MIN_DIM)) {

                LImage->Width = (int)(LImage->Width   (expance * AR));
                LImage->Height = (int)(LImage->Width / AR );
            }

            LImage->Left = LImageCenter.X - LImage->Width / 2;
            LImage->Top = LImageCenter.Y - LImage->Height / 2;
        }
        FLastDistance = EventInfo.Distance;
    }

    else if (EventInfo.GestureID == static_cast<short>(Vcl::Controls::igiPan)) {
        if (!EventInfo.Flags.Contains(TInteractiveGestureFlag::gfBegin) amp;amp;
                !EventInfo.Flags.Contains(TInteractiveGestureFlag::gfEnd)) {

            // move the image
            TImage * LImage = dynamic_cast<TImage*>(Image1);
            movement.x = EventInfo.Location.X - FLastLocation.x;
            movement.y = EventInfo.Location.Y - FLastLocation.y;

            LImage->Left  = movement.x;
            LImage->Top  = movement.y;
        }
        FLastLocation.x = EventInfo.Location.X;
        FLastLocation.y = EventInfo.Location.Y;
    }

} catch (Exception amp;e) {
    ShowMessage(e.Message);
}  }
 

AR является соотношением сторон изображения и MIN_DIM определяет минимальные размеры изображения для увеличения.

Движение кастрюли не так велико…

Я не знаю, как заставить фигуру вести себя в соответствии с масштабированием и перемещением изображения.

Родительская форма-это панель под изображением, а не изображение, поэтому форма полностью независима от изменений изображения.

Я не могу установить изображение в качестве родительской фигуры.

Любое предложение, направленное на получение желаемого результата, будет оценено по достоинству.

Движение сковороды не является плавным, потому EventInfo.Location.X что и EventInfo.Location.Y не изменяется плавным образом. Если я начну движение кастрюли и остановлюсь, даже если пальцы все еще EventInfo.Location продолжают меняться.

Есть ли способ избежать такого поведения?

Комментарии:

1. @Tomerikoo. Привет, Томерику, я хотел бы знать, почему ты отредактировал мой пост. Да, я допустил ошибку, написав «поведение», и я благодарю вас за ваше исправление, но почему другие изменения? Мой пост был непонятен? Я нарушил правила? Плохо заранее благодарить за возможные ответы в будущем? Когда я отредактировал сообщение, чтобы добавить второй вопрос, я хотел разделить два вопроса, это плохо? Итак, почему?

2. Сначала я отредактировал сообщение, чтобы исправить неправильное использование zoom-sdk тега. Этот тег предназначен для масштабирования видео приложения, а не для масштабирования изображений. Потом я просто исправил кое-какие мелочи. Что касается вашего другого вопроса, вопросы о переполнении стека действительно должны быть сосредоточены на одном вопросе, и задавание нескольких вопросов в одном может привести к тому, что ваш вопрос будет закрыт как слишком широкий. Я пытался помочь вам избежать этого, замаскировав множество вопросов