Шаблон команды: как я могу делать непрерывные действия? (например, перемещение объекта)

Предположим, я создаю программу, в которой пользователь может рисовать, а затем перемещать фигуры. MoveCommand тогда может выглядеть примерно так:

class MoveCommand {
public:
MoveCommand(Shape& shape, const Vector2f& offset) :
shape(shape), offset(offset)
{ }

void execute() {
shape.move(offset);
}

void undo() {
shape.move(-offset);
}
private:
Shape& shape;
Vector2f offset;
};

Это хорошо работает, но как я могу отобразить предварительный просмотр движения (когда пользователь удерживает кнопку мыши), а затем сохранить только окончательное смещение при отпускании кнопки мыши?

Должен ShapeEditor класс переместить форму, а затем создать MoveCommand на кнопку выпуска? Что делать, если код execute() не тривиально? Как я могу избежать дублирования кода в ShapeEditor а также MoveCommand?

0

Решение

Это хорошо работает, но как я могу отобразить предварительный просмотр движения (когда пользователь удерживает кнопку мыши), а затем сохранить только окончательное смещение при отпускании кнопки мыши?

Если я вас правильно понимаю, вы хотите сделать все движение невыполнимым / повторно выполнимым как одну операцию, одновременно анимируя каждое отдельное микродвижение, когда оно выполняется в интерактивном режиме в первый раз.

Один из способов сделать это — то, что вы предлагаете себе, — записывать команду отмены / возврата только после завершения движения. Как вы указали, это приводит к некоторому дублированию кода. На практике это не проблема, так как вы всегда можете выделить этот общий код.

Другой способ — создать MoveCommand для каждого микродвижения, а затем реализовать объединение команд как часть вашего стека отмены / повтора. Посмотрите, как это сделано в Qt.

2

Другие решения

Других решений пока нет …