Russian Qt Forum

Программирование => С/C++ => Тема начата: Igors от Сентябрь 03, 2014, 14:00



Название: Spinners + undo
Отправлено: Igors от Сентябрь 03, 2014, 14:00
Добрый день

Юзверь нажал спиннер и держит, соответствующий editText обновляется 3 раза в секунду. При этом требование - каждое изменение должно отображаться в UI немедленно (не ожидая отпускания мыши). А вот с точки зрения undo это одна операция, бесполезно/плохо накапливать сотни изменений одного параметра. Сейчас undo работает так же как если бы значение было введено вручную. Как это изменить для случая со спиннером?

Спасибо


Название: Re: Spinners + undo
Отправлено: Bepec от Сентябрь 03, 2014, 14:35
Cпиннер это как бы выпадающий список, нет? Не могу представить вашу ситуацию.

PS мб вы имеете в виду spinBox?


Название: Re: Spinners + undo
Отправлено: Igors от Сентябрь 03, 2014, 14:59
Cпиннер это как бы выпадающий список, нет? Не могу представить вашу ситуацию.

PS мб вы имеете в виду spinBox?
Спиннер выглядит как 2 маленькие стрелочки справа от редактируемого поля. В Qt это QSpinBox, но он мне не подошел, сделал свой - не суть, ф-ционал тот же.


Название: Re: Spinners + undo
Отправлено: Авварон от Сентябрь 03, 2014, 15:03
так а в чем проблема? анду фреймворк позволет мержить изменения


Название: Re: Spinners + undo
Отправлено: Igors от Сентябрь 04, 2014, 08:22
так а в чем проблема? анду фреймворк позволет мержить изменения
Он не используется, вместо этого Undo пишется в файл(ы) и объекты реально удаляются. А делать по их образцу мне не очень нравится. Пример из букваря
Код
C++ (Qt)
bool AppendText::mergeWith(const QUndoCommand *other)
{
   if (other->id() != id()) // make sure other is also an AppendText command
       return false;
   m_text += static_cast<const AppendText*>(other)->m_text;
   return true;
}
Ожидать уникальности id не приходится - в любом приложении масса редактируемых полей.


Название: Re: Spinners + undo
Отправлено: Old от Сентябрь 04, 2014, 09:00
Ожидать уникальности id не приходится - в любом приложении масса редактируемых полей.
Если пользователь будет успевать выполнить 5 команд в секунду, то для переполнения 32 битного инта ему придется потратить примерно 27 лет. Не каждый парень справиться с такой работой. :)


Название: Re: Spinners + undo
Отправлено: Igors от Сентябрь 04, 2014, 09:10
Если пользователь будет успевать выполнить 5 команд в секунду, то для переполнения 32 битного инта ему придется потратить примерно 27 лет. Не каждый парень справиться с такой работой. :)
Пример: при выборе айтема какие-то поля заполняются числами. Выбран др айтем - др числа. И куда мне здесь щемиться с тем уникальным id() ?


Название: Re: Spinners + undo
Отправлено: Old от Сентябрь 04, 2014, 09:14
Пример: при выборе айтема какие-то поля заполняются числами. Выбран др айтем - др числа. И куда мне здесь щемиться с тем уникальным id() ?
Одно действие - одна undo-команда, а внутри она может хранить сколько угодно чисел.
Пользователь кликнул комбобокс, сохранили все числа из полей в команде для возможности redo, и установили новые числа.
Еще раз пользователь кликнул - сохранили в команде текущие, установили новые.



Название: Re: Spinners + undo
Отправлено: Авварон от Сентябрь 04, 2014, 11:54
Одно действие - одна undo-команда, а внутри она может хранить сколько угодно чисел.
Пользователь кликнул комбобокс, сохранили все числа из полей в команде для возможности redo, и установили новые числа.
Еще раз пользователь кликнул - сохранили в команде текущие, установили новые.



Да, это не трубы гнуть.


Название: Re: Spinners + undo
Отправлено: Igors от Сентябрь 04, 2014, 13:03
Одно действие - одна undo-команда, а внутри она может хранить сколько угодно чисел.
Пользователь кликнул комбобокс, сохранили все числа из полей в команде для возможности redo, и установили новые числа.
Еще раз пользователь кликнул - сохранили в команде текущие, установили новые.
??? Не понял такого сценария. Сам выбор из комбо никак undo не касается - ведь никакие данные не были изменены. А в момент изменения если хотим уникальное id - его придется конструировать типа связки айтем + поле.  Выглядит как-то мутно и сложно.

Да, это не трубы гнуть.
Да, там знание букваря никак не помогает :) Впрочем и в данной теме тоже, скорее вредит. Почему напр не  так: заблокировать добавление в undo после первого изменения и разрешить его как только мышь отпущена?


Название: Re: Spinners + undo
Отправлено: GreatSnake от Сентябрь 04, 2014, 13:15
Юзверь нажал спиннер и держит, соответствующий editText обновляется 3 раза в секунду.
Что такое "соответствующий editText" ?


Название: Re: Spinners + undo
Отправлено: Igors от Сентябрь 04, 2014, 13:39
Что такое "соответствующий editText" ?
Аттач: юзер давит верхнюю стрелку, пока не отпустил будут последовательно появляться значения 34, 35. 36 ...(при шаге 1)


Название: Re: Spinners + undo
Отправлено: GreatSnake от Сентябрь 04, 2014, 13:44
В Qt это QSpinBox, но он мне не подошел, сделал свой - не суть, ф-ционал тот же.
В Qt undo/redo в таких случаях выключено.
Кто мешает Вам сделать так же ???

И чем не устроил Qt-ишный вариант?


Название: Re: Spinners + undo
Отправлено: Igors от Сентябрь 04, 2014, 14:55
В Qt undo/redo в таких случаях выключено.
Кто мешает Вам сделать так же Непонимающий
Как "так же"? (на какой пример/класс Вы ссылаетесь?)

И чем не устроил Qt-ишный вариант?
Тем что он не наследник QLineEdit. У меня везде используется свой виджет в который вставлен QLineEdit. Ну я туда же и спыннер добавил, теперь любое поле может его иметь. И еще мелочь: в Qt нет (или не нашел) возможности "ускориться"


Название: Re: Spinners + undo
Отправлено: GreatSnake от Сентябрь 04, 2014, 15:03
Как "так же"? (на какой пример/класс Вы ссылаетесь?)
Как в том же QAbstractSpinBox - undo/redo буфер меняется только при ручном изменении, а не при прямом по Up/Down, Wheel.

И еще мелочь: в Qt нет (или не нашел) возможности "ускориться"
Код
C++ (Qt)
QAbstractSpinBox::setAccelerated( true );

Кстати, а как Вы изменяете содержимое QLineEdit при нажатии на Up/Down?
Ведь его QLineEdit::setText() чистит undo/redo буфер:
Цитата: assistant
Setting this property clears the selection, clears the undo/redo history, moves the cursor to the end of the line and resets the modified property to false. The text is not validated when inserted with setText().


Название: Re: Spinners + undo
Отправлено: Igors от Сентябрь 04, 2014, 16:25
Код
C++ (Qt)
QAbstractSpinBox::setAccelerated( true );
Ну вот, я опять Вас запутал  (так получилось :)). У меня undo на уровне приема данных, пример

- юзер ввел число. Оно проверяется на валидность, возможно клампится. Если новое значение равно старому - ничего не делаем.  Иначе текущее значение параметра записывается в undo а новое принимается. При выполнении undo записанное значение замещает текущее и все UI обновляется. Что там было в clipboard - все равно.

В данном случае надо не только принять значение, но и перерисовать OpenGL сцену(ы). Поэтому setAccelerated не подходит, нужно не чаще а шаг больше. Это легко достигается: нажал и двигает мышу вверх - чем выше тем больше шаг. Но в Qt я этого не нашел


Название: Re: Spinners + undo
Отправлено: Igors от Сентябрь 10, 2014, 14:59
Сделал так

Код
C++ (Qt)
extern bool undoDisabled;
 
void Spinner::timerEvent( ..)
{
...
undoDisabled = true;
emit SignalSpinInc(mStep);
undoDisabled = false;
}
 
extern bool undoOpened;
 
void OpenUndo( void )
{
 if (undoDisabled) return;
 assert(!undoOpened);
 undoOpened = true;
}
 
void CloseUndo( void )
{
 if (undoDisabled) return;
 assert(undoOpened);
 undoOpened = false;
}
Ну и любая запись в undo должна проверять флажок undoOpened, если false - ничего не писать. Все это выглядит незатейливо (или примитивно), нет никаких паттернов с гордыми названиями типа "стратегия"  :) - ну может я просто не знаю как их применить.

Др схемы/предложения?

Спасибо