Эффективная отмена / повтор для мобильного приложения, похожего на Photoshop - PullRequest
1 голос
/ 12 июля 2010

Я пытаюсь написать приложение для рисования для мобильного устройства (Android), которое будет обладать чуть большей функциональностью, чем MS Paint (например, различные кисти и настройки кистей, выделения, слои), но не будет таким сложным, как Photoshop.,Мне нужно, чтобы мое приложение имело приличную функцию отмены / повтора.Неограниченная отмена / повтор, вероятно, невозможна.Я был бы счастлив, если бы я мог отменить последние действия пользователя (возможно, около 20 действий).

Основные подходы, которые я знаю для отмены / повторения:

  1. сохранить все состояние или только те биты, которые менялись после каждой операции.Отмена включает обновление состояния путем восстановления снимков.Плюсы: простота реализации Минусы: интенсивное использование памяти.

  2. используйте шаблон команды, где у каждой команды есть метод "выполнить действие" и "отменить действие".Чтобы отменить, вы просто вызываете действие отмены предыдущих команд.Плюсы: эффективная память, Минусы: гораздо сложнее в реализации.

Мои патологические сценарии отмены / повторения, которые я должен рассмотреть:

  • пользователь рисует весь холст за один раз, и вы хотите, чтобы вся эта операция была отменена, когда пользователь нажимает отмену.При выборе варианта 1 нам нужно сохранить растровое изображение размером всего холста.

  • пользователь что-то рисует, импортирует изображение 1.jpg на холст, делает еще несколько рисунков,1.jpg затем удаляется / изменяется в какой-то момент другим приложением, а затем пользователь хочет отменить, а затем повторить все свои действия в приложении рисования.Я действительно не уверен, как правильно отменить здесь без сохранения копии любого импортированного изображения, пока оно находится в стеке отмены.

Может кто-нибудь дать какие-либо рекомендации о том, как лучше всего выполнить отмену /повторить на мобильном устройстве, где память и скорость процессора низкие?Мне нравится простота 1 и 3, но кажется, что единственным реалистичным вариантом является 2. Я не уверен, как справиться с моим вторым патологическим примером с этой опцией.

Ответы [ 2 ]

2 голосов
/ 12 июля 2010

На iPhone Core Data встроена поддержка отмены и повтора.Просто сделайте так, чтобы ваша модель данных отражала нарисованные объекты, и вы можете легко перемещать ее назад и вперед между сохранениями.Обычно вы сохраняете процедуры и объекты, используемые для создания графики, вместо самой графики.


Редактировать:

ОК, но это лишь небольшая поддержка API для реализации номера 2 и не поможет с примерами, которые я дал.

Ключевая идея выполнения этой работы заключается в том, что вы не настраиваете свою модель данных для модальной и сохраняющей графический вывод программы, вы настраиваете ее на модальную и сохраняете процесс создания графического вывода.

Наивным способом создания графической программы было бы настроить поток данных следующим образом:

Input_UI-->Display_UI-->Data_Model

Пользователь манипулирует Input_UI, который напрямую изменяет экранную графику Display_UI.Только когда пользователь сохранит, Data_Model вступит в игру.Этот тип потока данных делает отмену / повтор (и другие вещи) очень сложным для реализации, особенно в рисовании, например, в программе композитинга.Каждая операция должна знать, как отменить себя, и должна уметь работать с измененной графикой.

Лучший способ - настроить поток данных следующим образом:

Input_UI-->Data_Model-->Display_UI

Пользователь манипулирует Input_UI, который связывается с Data_Model, который манипулирует выбранным пользователем.Data_Model записывает процесс, например, «добавить файл jpg.1 at rect {0,0,100,100}».Изменение в Data_Model отправляет уведомление в Display_UI, который считывает измененные данные и реализует описанный процесс.

Data_Model откатывается назад, а Display_UI просто рисует то, что сообщает Data_Model.Display_UI вообще не должен понимать процесс отмены.

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

Итак, в ваших примерах для программы компоновки:

  • Data_Model хранит координаты выбранной области (всего холста), которая все еще просто "rect {0,0,canvas.width, canvas.height} ", а затем операция" залить черным ".Для отмены Display_UI возвращает изображение к последней точке сохранения, а затем незаметно применяет изменения, сделанные до последнего -1.
  • Вам просто нужно сохранить кэш изображения до следующего сохранения.В этот момент Data_Modal фиксирует все изменения и экспортирует композицию в файл.При следующем запуске приложения оно начинается с изображения из последнего раза.Если вы хотите отменить бесконечное, то да, вы должны сохранить импортированное изображение навсегда.

Способ подойти к этому - игнорировать графический интерфейс и вместо этого подумать о том, как создать приложение для запуска из командной строки без ввода или вывода графического интерфейса.Data_Modal будет работать точно так же.Это позволит сохранить текстовые команды и данные (например, импортированные изображения) для создания выходного изображения, а не просто снимок изображения на экране.

1 голос
/ 12 июля 2010

Мне нравится простота 1 и 3, но кажется единственно реалистичным вариант 2.

Я не уверен, что такое "3", так как у вас есть только два варианта в вашем вопросе.

Что касается потребления памяти # 1, это проблема, только если вы используете память. Храните историю в памяти только до тех пор, пока для записи их на SD-карту требуется AsyncTask (или, возможно, обычный фоновый поток, отрабатывающий LinkedBlockingQueue). Нет SD-карты - нет отменить / повторить. При отмене, если ваша история уже записала его на диск, перезагрузите его с диска. Обязательно очистите SD-карту (удалите историю при чистом выходе, удалите все устаревшие файлы при следующем запуске).

Имейте в виду, что я никогда не писал приложение для рисования, не говоря уже о Android, и поэтому могут быть проблемы с производительностью (например, отмена может занять секунду, чтобы загрузить растровое изображение с SD-карты).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...