Всё правильно сделал… или пароль 10 символов
Поддался я на использование интернет-мема
ибо по-друому ситуацию ни в вебинаре сказать, ни в блоге описать. Эвфемизмы всё-таки несут в себе бранный оттенок, но наблюдаемой мной феномен нанёс мне чисто эстетические травмы, а крепкие слова я приберегу для описания эффективных технологических решений.
Что IT-шники, не люди? Тоже есть хотят!
И пластиковые деньги в виде (псевдо) кредитной карточки требуют дистанционного управления посредством web. Такое вот культурное начало рассказа о моих вчерашних траблов с интернет-банкингом моего bank-а (чуть не выругался).
Обычно для управления счётом через web-панельку (админку, приблудку, браузерный клиент) нужно ввести логин/пароль. Я довольно интенсивно пользуюсь данным средством, т.к. стараюсь переводить микроскопические суммы. Мне так кажется, что экономия больше. А раз часто делаю, то и логин/пароль не успеваю забыть. Пароль у меня длинный. Ыщтпыщаафшерфтввумщешщт или вроде того. Кто назовёт человека вниз головой, получит приз.
Your account is blocked
Потому что я ввёл 5 раз пароль, но не угадал ни одной буквы. Решается такой вопрос визитом в отделение банка. Что мне сказал менеджер банка. В системе аутентификации можно было задать пароль произвольной длины. Я это и сделал, когда активировал сервис 2 года назад. Внимание, пароль 15 символов.
А система безопасности реально внутри себя использовала 10-символьные пароли. Т.е. мой пароль был сохранён, но не все 15 символов, а только первые 10 из него. На протяжении 2 лет я вводил 15 символов, которые потом урезались до 10 и сравнивались с 10-ю, хранящимися в базе.
В какой-то момент систему переделали на "более 10 символов". И вводимый мной 15 символьный пароль уже без обрезания сравнивался с хранящимися в базе 10-ю символами. Ну и какой телепатией я должен был пользоваться при этом?
Решение
оказалось просты, о чём мне поведал добрейший и любезнейших менеджер. Вводить нужно пароль, но не весь, а только первые 10 символов.
Изящное решение. Сначала обрезать пароль до 10 символов, потом увеличить длину, а пользователя держать в неведении, уповая на то, что большинство клиентов не будут делать длинные (=безопасные) пароли.
Мораль
вывести из данной истории достаточно сложно, т.к. не ясна мотивация разработчика относительно первичного ограничения. 10 пальцев? Магия круглых чисел? Экономия пространства в БД? Использование экзотического немасштабируемого алгоритма сравнения? Хочется небольшой дискуссии по поводу ограничений, например, длины полей. А как вы, создавая поле таблицы "фио" (или "фамилия", если 1нф), выбираете длину?
Posted by Vsevolod Leonov on May 15th, 2012 under public | 9 Comments »FireMonkey Blocks
Сделал этот небольшой проект
по времени где-то за час. Может, больше. Но когда занимаешься любимым делом, то время летит незаметно. Цель была проста, как и раньше. Протестировать FireMonkey на предмет технологичности. Мне понравилось, совмести 2D и 3D влёгкую, удобно писал в "родной" среде.
Сделал давно
Ещё на день рождения Delphi. И тут как всегда возникает дилемма: доделать или не доделать? Вот если бы я участвовал в конкурсе, тогда да… Вполне полезная программа для детишек.
Не сделал
А зачем такая программа нужна? Куча полезных функций. От развития виртуально-пространственного мышления у детей до автоматической конвертации реалистичной модели в блочную конструкцию (наберите в поисковике "баскетболист из лего" и вы поймёте, о чём я). Я такие вещи видел вживую. Впечатляет. И вот можно сделать авто-конвертор. Может, кстати, и сделали. И вот такой алгоритм был-бы интересен. Сделать дискретизацию модели в блоки. Почему-то вспомнил "взятие интеграла методом прямоугольников".
Мне было интересно FireMonkey приладить к этому абсолютно естественному для 3D-фреймоврка делу.И уже приладив, вспомнил (честно!), что и для MacOS можно это сгенерировать по-быстрому. Получилось.
Внимание, мини-конкурс!
Цена вопроса - наградная флэшка Embarcadero, прекрасная чёрная стильная майка Embarcadero и бесплатный билет на конференцию. Если кто не планирует приехать в Москву на конференцию из-за отпуска, то (по крайней мере) можно будет на отдыхе дефилировать в брендовой майке, а внешний носитель передарить начальнику. Или наоборот.
В ролике вы увидели конструктор из блоков. Будет естественным предположить, что я сделал класс TMyBlock. Не могу сказать, что я им доволен. А какой бы вы написали класс для решения такой задачи?
Ответы присылайте сюда (не в комментарий к посту, не мне на почту, а именно туда). Там мы и обсудим, и выберем коллективно чемпиона. Или двух. Это совершенно естественно, что может быть несколько вариантов для решения этой задачи. Но при прочих равных победит тот, кто раньше опубликует (фора для любителей думать в выходные).
Достаточно лишь самого класса, без реализации. БЕЗ РЕАЛИЗАЦИИ! Просто покажите структуру + методы. Я свой тоже покажу. А вы поймете, почему он мне не нравится.
Но мне-то что? Майка у меня есть. Флэшка тоже. А вот на конференции мы с вами-то и встретимся!
IT-специалист стоит столько, сколько он знает
Хороших новостей
мало не бывает. Но здесь сразу после праздников начался некоторый "перебор". Тогда ранжируем по максимально широкому охвату масс IT-трудящихся. Есть и другие критерии, но выбор за вами. Я бы порекомендовал максимально расширять свои горизонты. Конечно, это нужно делать тщательно. Не чтивом всего подряд и хождением на всевозможные конференции. Вот поэтому мы (Embarcadero, Russia) совместно с компанией SoftwarePeople впервые в России предлагаем вам следующее.
Конференция "Кроссплатформа 2012"
Сайт конференции стоит того, чтобы:
Тщательный отбор
докладов был одной из основных задач, стоявших перед программным комитетом. Вот уж точно "ау, где вы - спикеры" откинули мы изначально. Приглашали только тех, кто:
- знаком разработчикам
- имеет, что рассказать
Нас не интересовали рафинированные доклады, абстрактные рассуждения на тему методологий разработки, некие измышления людей, считающих себя экспертами. Каждому потенциальному спикеру были даны рекомендации (не, не на тему "что говорить", эти люди - профессионалы), а по-поводу аудитории. Я всячески стремился продвигать тему разработки на Delphi и C++Builder.
Шокирующее
Несмотря на то, что очень многие доклады представлены Embarcadero и близкими компаниями, а это даёт нам право считать конференцию отчасти "своей", одним из ключевых гостей конференции будет корпорация Microsoft. Давно, очень давно я уже говорил, что "Microsoft и Embarcadero - братья навек", охлаждая тем самым неуёмный пыл завзятых холиварщиков. Кстати, именно их мы приглашаем на данную конференцию отдельно и настойчиво.
Огромное дельфийское спасибо Владу Дмитриеву, Microsoft, который оказал нам содействие в решении данной проблемы. Также с нетерпением ждём Дмитрия Сошникова и Алексея Шуленина. Подробности их презентаций в программе. Давайте узнаем всё про Windows 8 и MS SQL Server 2012 от представителей компании-производителя и на русском языке.
Как дельфист дельфисту
Очень ждём именно Бруно Фиеренса из TMS Software. 2 доклада - техническая презентация и мастер-класс. Демо-стенд в холле. Живое общение. Наглядные демонстрации. Из-за особенностей российского рынка мы несколько не в фокусе технологических партнёров и экспертов мирового уровня, поэтому г-н Фиеренс для нас - очень хорошая возможность резко повысить "капитализацию мозга". С нами будет общаться человек, эффективностью бизнеса которого доказана его компетенция в области Delphi и C++Builder.
От desktop к iPad
перейти не так уж просто. С одной стороны - FireMonkey даёт такую возможность. С другой - принципы построения интерфейса отличаются. Тем более, если у вас пока нет iPad-а. Кстати, может услышим что-то такое, что заставит нас всерьёз подумать о нём, как "недостающем" звене в цепочки тотальной компьютеризации человеческой деятельности. Артём Кузнецов - тот самый эксперт, который этот путь уже проделал с рядом вполне эффективных коммерческих внедрений.
… и другие доклады, о которых - в следующих постах
или прямо сейчас на сайте конференции. Регистрируйтесь, чтобы не "питаться аннотациями", а услышать и увидеть всё самим.
IT-специалист стоит столько, сколько он знает.
Кнопка
"зарегистрироваться" на сайте конференции пока не мигает (а как сделать "кнопку-мигалку" на FireMonkey я рассказывал), но её ненавязчивость не должна стать поводом её ненахождения.
Posted by Vsevolod Leonov on May 10th, 2012 under Uncategorized, public | 3 Comments »Конкурс FireMonkey: wDivision тестирование
FireMonkey для учёбы
Конкурс объявлен, участники мотивированы, работа идёт полным ходом. Вводный текст был посвящен "пилотному" проекту. Я провёл его тестирование под детской нагрузкой (в прямом, я не переносном смысле).
Тестировался общий функционал приложения wДеление, а эргономика здесь является составной, если не главной часть. Я бы даже посоветовал участникам конкурса (и самому себе, как параллельному участнику - да, я буду публиковать свой проект) не столько думать о хитроумных и сложных алгоритмах, сколько о притягательности и вовлекательной способности метафоры интерфейса.
Результаты
Тестирующий прошёл 2 полных цикла с повышением уровня сложности. Причём желание увеличить нагрузку было его собственным. Эргономика интерфейса вызвала одну лишь похвалу, поэтому мы коснёмся её отдельно. Здесь следует упомянуть, что в "бумажном" варианте делением "столбиков" в 22-00 было бы абсолютно нереализуемым с точки зрения организации такого процесса. Короче, в семье родителей-программистов с демократическими традициями и уважением прав ребёнка отец был бы вежливо послан незакомелексованным любителем компьютерных игр.
Анализ
Полезность: +10. Это не надо доказывать, т.к. деление столбиком есть базовая метода, преподаваемая в школьном курсе математики.
Эргономика - порог вхождения: +10. Ни разу не было ошибочного нажатия на кнопку или вопроса по использованию. Инструкция не нужна!
Эргономика - производительность в рабочем режиме: +10. Снижение производительности, рассеяние внимания замечено не было. Естественно, с поправкой на в принципе короткий цикл работы.
Вовлечение: +10. Работа велась с интересом, тестирующий не фиксировался на мысли о полном соответствии выполняемой им работы типовому школьному заданию.
Критика
Безусловно, результаты тестирования показали 100% попадание в цель. И то, что тестирующий получил удовольствие, выполнив задание, свидетельствует о высоком уровне компетенции разработчика. Но нужно и покритиковать:
- Панель набора цифр нетипичная. Наверное, лучше "слизать" с метафоры "калькулятор".
- Анимация должна идти быстрее, если мы говорим о том, что ведётся отсчёт времени на "результат".
- Чуть больше развлекательности.
А теперь то, что многим могло показаться неправильным, но это - самое правильное:
- Большая рабочая зона (столбик). Большие кнопки. Для Mac-овского touchpad-а это всеьма актуально. Да и "глубоко задумавшись" можно промахнуться.
- Список "победителей". Это хорошо стимулирует на повышение результата. Это не "портреты великих людей над классной доской", а возможность человека расти над собой и соревноваться с собой.
- Индикация прогресса заставляет удерживать концентрацию и заинтересованность в конечном комплексном результате.
Вы можете сказать, что всё это - тривиально и давно изучено в индустрии игр? Тогда я уверен, что у Вас получится не хуже.
Успехов!
Posted by Vsevolod Leonov on April 24th, 2012 under C++Builder XE2, Delphi XE2, FireMonkey | 9 Comments »FireMonkey для учёбы
Конкурс
Компания Embarcadero вместе с нашим мега-идеологически-культурно близким проектом DelphiFeeds объявили конкурс. Освоение новой технологии должно начинаться с простого, но яркого проекта с элементами креатива и развлекательной составляющей. Как раз в этом плане "школьная" тема подходит лучше всего. Никакой ребёнок не будет использовать программу с удовольствием, если там нет элемента игры. Причём тут не обязательны некие "персонажи" (на детском сленге - "персы", кто бы знал!). Достаточно добавить немного фантазии и интерактивности, а также наглядности за счёт анимации. FieMonkey здесь - незаменимый инструмент.
Школа
Хорошим эффектом от этого конкурса (помимо развития навыков использования новой платформы) является появления пусть пока умеренного, но ощутимого арсенала обучающих микро-прогармм. Конечно, мы можем сидеть и ждать, когда же, наконец, наши школы оснастят централизовано соответствующим инструментарием. Но можно провести и такой вот всероссийский IT-субботник. Также есть вариант возложить эту задачу на плечи учителей. Пусть учителя-энтузиасты сами и пишут. Это - пожалуйста. Если на конкурс будет представлена работа программиста, который - действующий учитель, то это как минимум будет означать востребованность продукта. А это также рекомендуется учитывать при выборе победителей.
Пилот
Мы крайне серьёзно отнеслись к этому конкурсу, поэтому даже провели небольшой "междусобойчик". Инициативная группа устроила небольшую "гонку вооружений". Я попытался сделать небольшую программку для обучения детишек таблице умножения. Помню, что мой сынуля исписал тонну бумаги, бесконечно дописывая "7×6=???". Поэтому мой проектик реализовывал собой крайне простую, но вполне жизнеспособную идею: две колонки, слева примеры, справа ответы. Скриншотить не буду. И так понятно. Потратил на это час, зато вспомнил алгоритм перемешивания элементов массива. Полезно.
Потом показал поделку другому участнику "предварительных заездов". В ответ получил массу критики за… практически за всё. Но критика чужого проекта чревата "взятием на слабо", что я тут же и сделал. Надо сказать, мой друг Whiler (не могу сказать, что дизайн интерфейсов - его сильная сторона). Зато программировать в Delphi этот достойный мужчина умеет превосходно, смотрим его галерею.
Именно там он сделал и опубликовал "программу для обучения школьников делению" (wDivistion).
Так как же российские школьники смогут её использовать? Она же на французском! А также на английском и на русском. Тут я внёс свой скромный вклад. Нет, не переводом сей чудной программульки на родной, а тем, что смог вдохновить моего скромного, но талантливого друга.
Кстати, примерные трудозатраты - 1 день работы с учётом, что это была первая программа на FireMonkey. Вполне достойна, чтобы получить приз конкурса (на мой взгляд).
FireMonkey
Почему именно данная технология?
1. Без яркого и броского интерфейса нечего пытаться сделать обучающую программу. А это уже не только сегмент "школьный", но и вполне бизнес-уровень. Вы сделали новую функцию, но пользователь должен а) научиться; б) привынкуть; в) отточить.
2. Низкий порог вхождения для классических Delphi-программистов.
3. Есть версия под MacOS, а именно эта техника достаточно интенсивно входит в сферу образования.
Тестирование
Пойду заставлю сына протестировать по-боевому. Здесь, кстати, и английская версия пригодится. Обязательно опубликую отчёт.
Posted by Vsevolod Leonov on April 23rd, 2012 under Uncategorized | 7 Comments »Кубик Рубика, не мой, но красивый (Rubik’s Cube, not my, but great)
ru
Один неслабый человек сделал свой кубик Рубика на FireMonkey.
Опубликовал там же исходники. Что можно сказать, большой молодец, респект!
Пожалуй, надо свой доделать. Но сейчас готовится конкурс. Следите за рекламой на DelphiFeeds.ru.
en
A really great developer’s published his own version of Rubik’s Cube wtih FireMonkey.
Really impressive, taking into account he completed the job and published his sources. Respect!
I’ve got to complete my version and publish the sources. Promise! But not soon.
Fireman, send me your photo and I’ll publish it here. May be a little story about the project will be also interesting for people. Drop me a line, please.
Posted by Vsevolod Leonov on April 19th, 2012 under C++Builder XE2, Delphi XE2, FireMonkey | 4 Comments »FireMonkey Styles for Blinking Button
The problem
appeared when discussing "Scalability of enterprise DBMS-targeted systems" (in English on massive demand in comments) with Dmitriy Kouzmenko, Russian expert in InterBase since its origin. Then this occasional topic called more interest, so now I have to give some light to the this. The initial idea was how to make a user press "backup db" button. Or how to force or even pester him/her into doing this. Quite an appropriate variant is to create "blinking button".
The ergonomics
Before we start our tour into technical valley of using FireMonkey Styles, let’s speak about some concept. The visual component a-la "blinking button" is not very often to see in user interface, so not being too creative let’s make some analysis.
Usually some traditional interface waits for an action by a user and then repsonds as beginning to execute some task. So it’s quite ok, when the user does something and that’s a trigger for some procedure.
Sometimes the interface needs to notify the user of something. We do use this assynchnotous interaction when doing multi-thread programming. Basically we start child thread and then it indicates (remember? Synchronize) that….
- mission accomplished
- mission failed
- don’t worry, I’m doing something
If first two items are typical to show the results of some hidden operation, then the third type of indication is used to distract the user from sad thought: "oh, no! I’m hanging again!". But really this is not big deal of informing the user of the excact figures (for example, in %). In most cases operations executed are non-linear, and 75% doesn’t denote we are ¾ ready. Moreover, intuitively we feel the closer to the end the higher risk of failure.
Of course, if you fully control the algorithm you can calculate the %, but it’s not critical. And in some cases it’s good to find better metaphor, especially, with FireMonkey. Look at TProgressBar (C:\Users\Public\Documents\RAD Studio\9.0\Samples\FireMonkey\ControlsDemo). Main bar indicates the status and the “secondary” light is travelling along the (green) bar to relax the user when waiting too long even for next “growth“ of the main status indicator.
Instead of blinking
All the said above is rather trivial. Since long ago we could use from ProgresBar/StatusBar, avi-gif-like animation (deletion in Explorer), animated cursor up (sandglass) to complex multi-thread operation status metaphor (see, for example, multi-thread download indicator progress in FlashGet). But we need not passive, but active or compelling effect from a control.
One should note, that in Windows 7 a taskbar button also allows locating some progress indication in itself (try massive copying in Explorer and watch it). After Embarcadero had released Delphi 2010 we all could do the same, and Andreano Lanusse instructed us how to do this then. But let’s think rather of universal metaphors, or unique ones, because we should do all things in multi-platform manner.
TryIcon provides more “imperative”, and it’s blinking draws attention and calls the user to understand by clicking it, what is hidden behind and what was a reason of the show. But once again, this metaphor is good for Windows, but let’s think of the current and future variety of platforms, supported by FireMonkey.
I believe, the "blinking button" is quite good approach for constant and annoying reminder. The point is how can we do this with little handcoding and according to the spirit of FireMonkey.
Constructing the style
My intention is to make “button-the-pest” with FM Styles, rather than some typical programming. If you’re going to be rather smooth, replay the webinar on styles with Eugene Kryukov. And now “blinking” is a very good test drive for FireMonkey on unexpected landscape.
Add two buttons (TButton) to the main single form of a new FireMonkey HD application. Fist button will be our "blinker", the other will start the show.
In order to change the button style from “normal and calm” to “nervous and ticking”, pick the patient (Button1) and right-mouse-click on it. In the list in pop-up menu select “Edit Custom Sytle”. Now all the other buttons on the form (Button2 and more) have the style “by default”, while Button1 is visually different. Then we’ll see the style designer.
I’m now showing some part of the designer window, which demonstrates the structure of the button. The designer itself is rather new, but the way of using is very familiar, as we’re going to do this with ObjectInspector.
We can see some “animations” (TAnimation), but it doesn’t mean something will move to and fro. Once I tried to explain the “abstract” functionality of animation in FireMonkey. Now we see TColorAnimation, which will change some colors, and we need only ParentProperty, Start, Stop and Trigger to understand (but “understand” is too much for this). Just to see.
When a user drives a cursor across the button, this switches the animation on. The color doesn’t change instantly, and no place to guess how long it will take place. Look at Duration property. And for “blinking” effect we need to loop the color changing (Loop property), set AutoReverse to true and, may be, make the colors brighter.
As simple as that
The first TColorAnimation is fired by the trigger “IsMouseOver=true” (see the corresponding property in ObjectInspector). The second one – by “IsMouseOver=false”. We’ll do them that way: when the cursor is over, the button will stop blinking. I’ll set Start and Stop properties to Lawngreen. If you hate spring grass, feel free not to follow me at this point.
Then let’s align the second animation, which is more important. When the cursor leaves the button (sluggish and indecisive user) without pressing it, the button should continue blinking. That’s the core of all the buzz. Set the Start property to #FFEFEFEF (copy it from Stop property), and change Stop property to the most aggressive color (Red, for example). Then, please, loop and auto-reverse the animation by the Loop and AutoReverse properties (no surprise? Ok, who’s said he needed huge documentation to start using FireMonkey?)
Now we can press Apply and Close button in the style designer, then save and run the project. You’ll see the form with two buttons, if you let your mouse cursor walk on Button1, it will first become green, and then start showing the alarm.
Technological prototype
Let’s see C:\Users\Public\Documents\RAD Studio\9.0\Samples\FireMonkey\ControlsDemo. This time we’re not going to analyze “the ergonomics”, but “the source code”. TProgressBar is not blinking, but we can see “self-inducing” animation without triggering (as some external activity by a user).
Now we know, the similar visual component exists (=we can also do the same). There are no principle technological obstacles, so it’s time to act:
- in the form select Button1, right-click, and then "Edit Custom Style…"
- open the Button1Style1 structure as shown below
- find in the tool palette TColorAnimation component
- pick it, drag it, drop it on the appropriate TRectangle
You needn’t follow this particular red line exactly when dragging. You’re free use different path.
After adding the third animation to the custom button sytle the structure will be as shown:
Then for your convinience, please, find the set of properties of this new-born third animation:
Comment 1. What format is preferable for you personally? Youtube videos or rich texts with screen-shots? Please, post your choice in comments.
Comment 2. The very old-school drag-n-dropping method was demonstrated only to make the demo maximally reproducible. I’ve already done this 3 times faster by copy-pasting the form text (right click in the form, View As Text, as for style-making this is more productive).
We are now one step to target. We need to be able to start "blinking". But first repeat the theory:
- animation is very natural when used in styles, but the most common is color animation;
- style even for simple component can contain many objects-animations, applied to different graphical primitives inside the style structure;
- we recommend to use many animations not simultaneously, but in sequence; timelining them with different triggers (MouseOver=true, MouseOver=false) not to interfere;
- animation effects are fired by some trigger, so even "self-inducing" animation is controlled by this mechanism.
This very paragraph might be the only non-trivial idea in this post. We’re selecting the new animation and setting their trigger as IsVisible=true. When pressing Button2 we react as
procedure TForm1.Button2Click(Sender: TObject); begin Button1.StartTriggerAnimation(Button1, ‘IsVisible=true’); end;
Comment 3. Please, don’t try the obvious, but ineffectual property Enabled. It won’t work. It works only for animation effects, created and aligned in the designer for FM forms, not styles. For styling FireMonkey comonents we should use triggers.
Done now calm
Let’s summarize. We replaced our "by default" style of Button1 and created our custom one. It was automatically set in property StyleLookup of the button. If you want to cancel our custome style and back up the "default" one, it’s easy: Button1.StyleLookup := ”. The created custome style is stored in the form text (look at fmx-file or "View as Text"). In the form you can find the new style in component StyleBook1 : TStyleBook (added automatically as we had made some new).
I’ve, of course and as usual, tested the application on MacOS. The colors are brighter, and we’ve already explained this phenomeon. But the animation happened to be more smooth, with no sudden delays, and chaning due to triggers were seamless. Next time, I’ll make the recording from my Mac directly.
Project BlinkingButton.zip.
Posted by Vsevolod Leonov on April 12th, 2012 under C++Builder XE2, Delphi XE2, FireMonkey, Uncategorized | Comment now »FireMonkey - Мигающая кнопка
Постановка задачи
родилась в ходе дискуссий на тему принуждения пользователя "сохранять базу" (делать backup). Дискуссия возникла случайно при разговоре с Дмитрием Кузьменко о "Масштабируемости корпоративных систем на основе СУБД".
Затем эта тема подверглась дальнейшему развитию в плане попыток выяснить возможности реализации "мерцающей кнопки" на компонентной основе FireMonkey.
Эргономика интерфейса
Прежде чем углубиться в рассмотрение технологии, нужно немного времени уделить идеологии. Не такой уж и часто встречающийся элемент интерфейса - "нечто-с-мигалкой". Нас даже могут упрекнуть в излишнем креативе. Давайте сделаем правильный заход.
Интерфейс пользователя по своей сути в классическом исполнении является синхронным. Пользователь сделал некое действие - увидел результат. Но бывает, что приложение вынуждено (не дожидаясь воздействия со стороны пользователя) уведомить пользователя в одностороннем порядке. Часто это есть результат работы вторичного потока - мы стартанули задачу, она работает сама по себе где-то за кулисами (вне явных интерфейсных проявлений), а потом сообщает пользователю о том, что …
- процесс завершён
- операция закончилась неудачей в течение выполнения
- просто уведомление о текущем статусе/состоянии
Если первые два пункта характерны для вывода скрытой операции "из тени", то третий пункт часто сводится к отвлечению пользователя от грустных мыслей о зависании приложения. Благое намерение сообщить пользователю о статусе операции (например, в %), чтобы можно было предугадывать срок окончания несколько наивно, ибо интуитивно мы чувствуем нелинейность и нарастание напряжения. Чем ближе к концу, тем выше риск сбоя. Да и процессы немонотонны и нелинейны, поэтому 75% совсем не означает, что через 1/4 прошедшего времени операция закончится. Или что на 75% сбой остался позади.
Императив
Рассмотренное выше является тривиальным. Это и привычно, и легко реализуемо. Здесь мы начинаем от простых техник в виде ProgressBar/StatusBar, "анимашки" (полёт листочков в корзинку), формы и анимации курсора (а-ля "песочные часики") до кульминации в виде комплексной индикации статуса многопоточной задачи (например, закачки в FlashGet).
Следует сказать, что в Windows 7 кнопка на панели задач тоже позволяет показывать степень выполнения текущего процесса приложением (чтобы вспомнить, попробуйте покопировать что-нибудь в проводнике в большом объеме и посмотрите, как будет выглядеть кнопка на панели задача). После выпуска Delphi 2010, которая поддержала разработку под Windows 7, варианты решения данной задачи были опубликованы в исходных кодах на Delphi, но сейчас нет смысла к этому возвращаться. Ввиду возможности мультри-платформенной разработки данный функционал потерял актуальность, да и чисто визуально данное решение нельзя считать удачным. Хотите поспорить? Комментарии внизу.
С TrayIcon ("иконка-в-трее") дела обстоят чуть лучше. Она обладает неким "императивом", т.е. её навязчивость принуждает пользователя сделать действие - кликнуть и узнать, что же там так трепетно бьётся (непрочитанное сообщение, уведомление и т.д.). И чем более суетливым является движение, тем более навязчивым становится желание от него избавиться. Но здесь опять позволю себе напомнить, что мультри-платформенная разработка и унификация интерфейсов для desktop и mobile (и даже web) перечёркивает планы использования платформенно-зависимых метафор.
Так что идея "мигающей кнопки" вполне себе интересна. Она реально побуждает пользователя нажать на неё. Вот бы еще изготовление оказалось технологичным!
Конструктив
Мне захотелось попробовать сделать "кнопку-мигалку-надоедалку" с использованием стилей. Если вам хочется достичь лёгкости в данной технологии - зацените вебинар с Евгением Крюковым, архитектором FireMonkey, по теме Styles. Сейчас зададим "стилям" в FireMonkey неслабый crash-test. Потянут ли?
Для начала разместите на форме нового проекта FireMonkey HD две кнопки. Первая будет подопытной. Вторая - управляющей.
Чтобы поменять стиль кнопки с "кнопка адекватная" на "кнопка с нервным тиком" выберем пациента (Button1) и прищемим его правой кнопкой. В списке лекарств выберем "Edit Custom Style…". Теперь все остальные кнопки на форме (Button2) будут иметь стиль "by default", а эта - свой собственный. После этого откроется дизайнер стилей.
Ну как выглядит кнопка я показывать не буду, а вот из чего она состоит - стоит посмотреть. Теперь кнопка в FireMonkey представляет собой сложную структурную композицию, состоящую из объектов: визуальных компонентов, анимаций и эффектов. И настраиваются они в "инспекторе объектов". Поэтому некоторая степень новизны процесса компенсируется привычными приемами работы.
Здесь я рекомендую посмотреть, какой объект за что отвечает. Анимация, кстати, это не когда "что-то где-то движется". В FireMonkey анимация как объект имеет более обобщенный смысл - изменения свойства родительского объекта во времени. Я уже высказывался по данному вопросу, но не касался изменения цвета во времени. Посмотрите TColorAnimation все 2 раза, особенно свойства ParenProperty, Start, Stop и Trigger. Вам нужна справка? Не смешите, здесь всё очевидно.
Когда пользователь наводит мышью на кнопку, то включается анимация. Изменение цвета кнопки не происходит мгновенно, это легко доказать, посмотрев на значение свойства Duration. Что нам остается? Немного перенастроить текущие цветовые анимации (просто зациклив их для постоянного мигания свойством Loop, да и яркости можно добавить).
Позитив
начинается тогда, когда понимаешь, что делаешь. Давайте разберёмся. Первый TColorAnimation управляется триггером "IsMouseOver=true" (свойство Trigger в ObjectInspector). Второй - триггером "IsMouseOver=false". Здесь нужно будет просто сделать так, что когда мышка наводится на кнопку (первая анимация), то кнопка переставала ужасающе мигать, привлекая к себе внимание, но намекала на полезный результат в случае её нажатия. Я ей и Start и Stop поставил в Lawngreen ("зелень на лужайке"). Если мои вкусовые предпочтения вам не нравятся (да и мне самому местами тоже), то функционал не пострадает от выбора другого цвета.
Теперь давайте зарядим вторую анимацию. Здесь дела поважнее. Когда пользователь надвигает курсор на кнопку, та замирает и перестает мигать. А вот когда он (нерешительная дрянь и тряпка) убирает мышку, так и не нажав, то кнопка должна начать световое шоу по-новому. Т.е. для второй анимации мы сейчас и оформим эффект "мигания". Я предлагаю свойство Start выставить в #FFEFEFEF (просто скопируйте значение из свойства Stop), а в свойство Stop внесите какое-нибудь радикальное значение. Я поставил Red. Теперь зацикливаем анимацию установкой Loop=true и AutoReverse=true. У кого есть здравый смысл, интуиция и минимальные знания английского языка, тому справка ненужна.
Теперь уже можно запустить программу (некоторые предпочитают предварительно откомпилировать её). Нажимаем Apply and Close в дизайнере стилей, далее действуем согласно многолетней привычке. Подсказок в виде скрин-шотов не будет, но у вас должно получится форма с двумя кнопками. При наведении курсора на первую из них, она заливается радикально зелёным, а при уходе курсора она должна начать тревожно мигать.
Креатив
бывает разный. У программистов (как у любых других инженеров-изобретателей) он выражается в умении приспособить некий инструмент/метод для решения определенной задачи. Задача такова - заставить кнопку мигать саму по себе, без всяких триггеров (т.е. без всякой внешней силы в виде действий пользователя).
Демо-проекты к Delphi XE2 находятся здесь: C:\Users\Public\Documents\RAD Studio\9.0\Samples\FireMonkey. Нас интересует проект "ControlsDemo". Там есть компонент, который анимируется сам по себе, без внешнего воздействия. Вам еще нужна справка? (подсказка, TProgressBar).
Теперь мы знаем, что сам-по-себе-анимирующийся компонент существует в природе. Добавляем еще одну анимацию (TColorAnimation) к нашей кнопке, которую мы опять открыли в дизайнере стилей: правой мышкой Edit Custom Style… Потом притащили за уши найденный в палитре компонентов TColorAnimation и скинули его на нужный TRectangle (показано ниже).
При перетаскивании компонента не обязательно строго следовать красной линии. Вполне можно срезать угол.
После этого ваш конструктор стиля кнопки будет выглядеть так, как показано еще ниже:
Теперь зададим свойства выделенного нового компонента ColorAnimation1 : TColorAnimation так, как показано ниже нижнего.
Примечание 1. Я уже реально подустал сейвить скрины шотами. Если что-то из живых роликов вам больше нравится, чем чтение экранов, пожалуйста, напишите в комментариях. Меня просто проинструктировали, что есть OldSchool, а есть NewSchool. Типа для "старичков" нужно писать и картинки лепить, а для "молодой поросли" нужны youtube-ные ролики. Отпишитесь внизу, если не лень.
Примечание 2. Именно такая старинная техника буксировки здесь продемонстрирована лишь во благо воспроизводимости примера. Естественно, я давно всё это сделал в 3 раза быстрее, слегка покопипастив в тексте формы (правый клик на форме, View As Text, и такое вот "невизуальное" создание стилей также нужно уметь делать).
Осталось совсем чуть-чуть. Нужно уметь включать мигалку. Еще раз повторим:
- стилю компонента свойственно использование анимации, которая применима наиболее эффективно к цветовому решению компонента;
- стиль компонента может содержать много разных объектов-анимаций, применимых к разным графическим примитивам внутри стиля;
- желательно применять эффекты анимации (цвета) последовательно, разводя их во времени за счет использования различных триггеров (например, MouseOver=true, MouseOver=false);
- эффект анимации должен включатся каким-либо триггером, поэтому даже "самопроизвольная" анимация должна управляться именно таким механизмом.
Вот последний пункт - некоторое нетривиальное звено в рассуждениях. Для самопроизвольного мигания берем новую анимацию и назначаем ей триггер IsVisible=true. Теперь мы можем, при нажатии на вторую кнопку (событие OnClick) написать следующие строчки:
procedure TForm1.Button2Click(Sender: TObject); begin Button1.StartTriggerAnimation(Button1, 'IsVisible=true'); end;
Примечание 3. Хочу уберечь вас от тривиального, явного и, к сожалению, неправильного решения поработать со свойством Enabled у нашей анимации. Не поможет. Это работает только при использовании анимации в design-time обычным способом. В стилях нужно использовать механизм триггеров.
Завершив
необходимые действия по реализации эффекта мигания для решения вполне конкретной задачи в области проектирования интерфейса - создание явных побудительных мотивов у пользователя к выполнению некой активности, можно чуть коснуться технических моментов работы со стилями.
Итак, мы поменяли нашей Buton1 стиль. Изначально он "by default". Но мы ему создали "Custom". Он прописался в свойстве StyleLookup кнопки. Если вам нужно сделать кнопку обычной, то достаточно сделать StyleLookup := ”, а созданный нами пользовательский стиль Button1Style1 хранится в невизуальном компоненте формы StyleBook1 : TStyleBook.
Проверка FireMonkey на платформе MacOS показала точное воспроизведение нужных эффектов, только (почему-то) мигание более плавное, менее прерывистое и (как всегда) очень красивое отображение цвета. Пожалуй, пора рекордить скрины на Mac-е.
Проект BlinkingButton.zip.
Posted by Vsevolod Leonov on April 11th, 2012 under C++Builder XE2, Delphi XE2, FireMonkey | 10 Comments »Вебинар #1 с Дмитрием Кузьменко, InterBase (запись)
Вы можете скачать запись вебинара с Дмитрием Кузьменко, посвященного проблемам создания и эксплуатации масштабируемых корпоративных систем на примере InterBase.
Масштабируемость (scalability) является одним из самых жёстких требований к информационным системам. Не всегда и далеко не всякая технология способна "растягиваться" без потери функциональности, если вообще это бывает возможно (потому что сохранение функционала в таких случаях означает его новый качественный уровень). Конечно, потребности бизнеса (в смысле совокупности бизнес-процессов, подчинённых бизнес-правилам) можно предсказать даже на начальных стадиях, но ранняя ставка на масштабируемость требует слишком больших исходных затрат. Причём дело не в материальном/временном эквиваленте, а в нехватке экспертных знаний. Просто мало таких людей, да и "найти и расспросить" часто бывает сложно.
А как без эксперта? Тоже можно, но долго и сложно: нужно заниматься исследовательским проектированием/программированием. Или вообще отложить фазу технического анализа масштабируемости "на потом" с повышением риска её отсутствия для системы в будущем.
Здесь представлена первая серия "экспертных вебинаров" на тему использования СУБД для построения корпоративных систем на примере InterBase. Ждём следующих таких активностей и присылаем вопросы.
Posted by Vsevolod Leonov on March 20th, 2012 under InterBase, Recorded Webinars | 7 Comments »FireMonkey Styles with Eugene Kryukov, webinar (recording)
This video replays the webinar with Eugene Kryukov, one of FireMonkey architect and developer, on styles.
… and you’ll see:
- Styles is a fundamental mechanism, it’s a must to use FireMonkey proper way and with maximum effectiveness.
- Styles is not just skins.
- Styles fully define the design of a control and its partial functionality. Here "partial functionality" means "visual behavior".
- A component should always have some style. The component is structurally empty, if it doesn’t possess a style.
- There are different style types: "by default" and "custom".
- A style can be built in the application, can be stored in an external file, but this difference is about storage only.
- Styles can’t be purely arbitrary, as they define the "visual functionality". Inventing a style, one should think over a particular component.
- Styles are very flexible and universal mechanism, which needs deep understanding.














RSS Feed

Connect with Us