October 2030
| |
|
1 |
2 |
3 |
4 |
5 |
| 6 |
7 |
8 |
9 |
10 |
11 |
12 |
| 13 |
14 |
15 |
16 |
17 |
18 |
19 |
| 20 |
21 |
22 |
23 |
24 |
25 |
26 |
| 27 |
28 |
29 |
30 |
31 |
|
6/12/18 06:30 am
C#, Симпатичное окошко "О программе"
 Можно сказать, по многочисленным просьбам зрителей. Итак, спрашивали, как устроено в наших программах окошко "О программе" с "эффектом титров". Т.е. список разработчиков и прочее медленно выплывает снизу, проползает по форме и исчезает наверху, часть всплывающих строк останавливается в центре формы, в конце выплывает слоган, так же останавливающийся на некоторое время в центре. Смотреть анимациюНа самом деле, форма была устроена ужасно, написана совсем другими людьми для другого проекта, а у нас кочевала из программы в программу без особых изменений, строки добавлялись в 3 ArrayList в коде формы, в функции рисования были какие-то непонятные жестко заданные поправочные коэффициенты, подобранные на глаз, и т.д. Решили немного поправить и все переделать. Не знаю, насколько получилось лучше, но понятнее и универсальней точно. Далее будет не столько код с пояснениями, сколько попытка показать, как мы рассуждали, переделывая форму. Определение сущностейСначала надо определить с какими данными мы будем работать. В первую очередь, мы выводим набор строк, т.е. первая сущность это строка, у строки может быть задан шрифт и цвет текста, и, собственно, содержимое строки - это будут явные параметры сущности. В процессе добавился еще один, неявный параметр - номер сценыШрифт целесообразно выделить в отдельную сущность. Во-первых, все используемые шрифты желательно загрузить и сформировать до вывода строк, во-вторых, у шрифта куча своих параметров, и задавать их для каждой отдельной строки неудобно. Параметры шрифта это FontFamily (Arial, Times New Roman и т.д.), размер и начертание или стиль ( жирный, курсив, подчеркнутый, зачеркнутый, или все вместе). Для того, чтобы связать шрифт со строкой, пришлось добавить еще один параметр внутреннее имя, по которому программа будет узнавать, какой шрифт к какой строке применить. Последняя сущность это группа строк, или сцена, поскольку строки выводятся группами (см. анимацию). К сцене мы приписали следующие параметры: цвет фона, скорость прокрутки строк (технически задается как таймаут таймера прорисовки) и время паузы (для эффекта остановки группы строк посередине формы, см. анимацию). Неявным параметром будет номер, его зададим позже автоматически, а также высота всех строк сцены и их количество. Формат данныхНегоже задавать эту кучу параметров непосредственно в коде, поэтому пришлось подумать над форматом данных. Решено было хранить описание строк, шрифтов и сцен в виде простого текстового файла следующего формата: ... команда;параметр1;параметр2;параметр3 [...] команда;параметр1;параметр2;параметр3 [...] команда;параметр1;параметр2;параметр3 [...] ...Формат команд следующий (в квадратных скобках необязательные параметры): Шрифт: addfont; FontFamily; Размер (pt, float); [Стиль]; Внутреннее_имяНапример: addfont; Arial;9;Bold;Group; addfont; Microsoft Sans Serif;8;;Names; addfont; Arial;14;Bold italic;Slogan;Строка: addstring; Строка; [Имя_шрифта]; [цвет_текста];Например: addstring;Make code, not war! C# like you.;Slogan;FF FF 00;Сцена: scene; [цвет_фона];[скорость_таймера_прорисовки ms];[пауза ms]Например: scene;20;3000;Цвет текста задается в шестнадцатеричном формате через пробел(ы): R G B [Alpha] Например: FF FF 00 - желтый FF 00 00 80 - красный с прозрачностью Начертания (стили) шрифта перечисляются через пробел(ы), от регистра не зависят. Структуры для хранения данныхШрифты: Генерируются при анализе "скрипта", и помещаются в приватный Dictionary<string, Font>, где строковый ключ - заданное "внутреннее имя" шрифта. Строка: Текст и параметры хранятся в специальной структуре: private struct AboutString
{
public string Text;
public string FontName;
public Color TextColor;
public int SceneNumber;
}А все строки в private List<AboutString> StringsСцена: Для описания сцены так же создана структура: private struct AboutScene
{
public int PauseTimeout;
public int StringsHeight;
public int StringsCount;
public Color BackColor;
public int DrawTimeout;
}И описания сцен так же хранятся в private List<AboutScene> ScenesЗаметки про парсинг- последняя точка с запятой является необязательной - пустые строки, или строки, содержащие только пробельные символы, пропускаются - команды приводятся к нижнему регистру (т.е. они регистронезависимы) - есть возможность оставить однострочный комментарий, начинающейся с ~ (тильды). Все, что после знака ~ считается комментарием и пропускается при анализе "скрипта". - если первая (нулевая) сцена явно не определена, то создается сцена с параметрами по умолчанию Команды, благо их немного, последовательно анализируются с помощью конструкции switch/case и передаются в функции добавления шрифта, строк, или сцены, где анализируются далее. Параметры и команда разбираются с помощью string.split(';');Некоторые вспомогательные функции для парсингаРазмер шрифта должен быть float, поэтому надо сделать функцию-обертку над Convert, так, как я писал об этом ранее: private float ConvertToFloat(string Number)
{
NumberFormatInfo format = new NumberFormatInfo();
format.NumberDecimalSeparator = ".";
return (float)Convert.ToDouble(Number, format);
}Некоторые параметры передаются через пробел (значения RGBA цвета, или стили шрифта). Нужна функция, которая будет избавляться от дублирующих пробелов, поскольку лишний пробел поставить легко, а вот вылавливать его потом неприятно: private string RemoveDupSpaces(string s)
{
while (s.Contains(" "))
{
s = s.Replace(" ", "");
}
return s;
}Заметки о реализацииЕстественно, весь функционал не стоит реализовывать прямо на форме, потому вся работа вынесена в отдельный класс AboutDrawer, который парсит переданный скрипт и занимается отрисовкой строк на форме. На форме строки отображаются в компоненте PictureBox, который передается в конструктор класса. Конструктор также устанавливает некоторые параметры по умолчанию. Поскольку, класс все равно работает с компонентами формы, то спокойно подключаем пространство имен System.Windows.Forms, и пользуемся всеми его возможностями. Например, в классе создаются два таймера ( Timer). Внутри обработчика события Tick одного из них, происходит отрисовка, а другой используется для эффекта паузы. В классе созданы открытые свойства для установки цвета фона, цвета текста по умолчанию, и размера расстояния между строк. Подробнее ознакомиться с кодом примера можно на Github: Код на GitHubЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2018/06/11/c-simpatichnoe-okoshko-o-programme/
6/12/18, 07:07 am
Очередной номенант на премнию Тюринга?
6/12/18, 11:43 pm
А че, Трамп настолько подкосил американскую науку, что даже мы таки да?
(Anonymous)
6/12/18, 10:10 am
Такой хуйней можно хвасться только учась в 3 классе школы. В 5 классе уже должно быть стыдно.
6/12/18, 05:05 pm
Так а никто не хвастается, просто симпатичное окошко.
6/13/18, 08:38 am
отличное пособие по тому, как никогда не надо делать парзеры.
6/13/18, 10:00 pm
Подскажи как надо, переделаем.
6/13/18, 10:13 pm
для вашего случая задача вообще решается регулярками, которые наличествуют в стандартной библиотеке.
6/15/18, 09:09 pm
На мой взгляд, регулярки сложнее с точки зрения читабельности кода и для понимания вообще. Это как из пушки по воробьям... Регулярное выражение нужно там, где надо найти определенную структуру, спрятанную в плейнтексте. Или я ошибаюсь?
6/15/18, 09:13 pm
регулярные выражения нужны тогда, когда у тебя есть текст, который надо обработать, и который возможно обработать регулярными выражениями. вот ровно в этот момент они становятся нужны. а вот делать очень хуёвый ручной парзинг (а здесь он очень хуёвый) — не надо вообще никогда. это можно было бы оправдать, если бы парзилось руками для производительности — но нет, по производительности этот парзер отсасывает как три турбины.
6/15/18, 09:28 pm
Блин, регулярных выражений для относительно сложного случая я побаиваюсь. Попробую, конечно, сам, но ежили не влом, скинь какой-нибудь концепнуальный мануал про регулярные... Все равно, хотел давно их как-то подучить, а вот ты мне и повод подкинул.
6/15/18, 09:42 pm
а чего там мануалить-то: они простые как полено. сопоставление строки с регулярно повторяющимися подстроками — вот и всё. реально — это всё. остальное — просто синтаксический сахар для удобства записи.
6/16/18, 11:57 pm
Там скорее синтаксическая соль, я проще в египетских (кеми) иероглифах, даже без Краеугольного Камня разберусь, чем в регулярках, так что посвяти в таинство, пожалуйста.

6/17/18, 12:12 am
да всё просто. ты досовые вилдкарды помнишь? те самые, которые '?' и '*'? так вот это оно (и да, ты пользовался регулярками каждый день кучу лет, оказывается — это совсем нестрашно ;-). разница лишь в том, что в вилдкардах всегда подразумевается any char, а в более продвинутых регулярках можно задавать образец для повторения.
а теперь от философии к технологии. все регулярные выражения — это просто запись фразы «повтори вот этот кусок некоторое количество раз». фактически, это обычная нотация «образец-операция». примеры: 'a*' — повторить 'a' от нуля до дохуя раз 'a?' — повторить 'a' ноль раз или один раз 'abc*def' — вот тут надо помнить, что «образец» может состоять из кучи элементов, и поэтому: повторить 'abc' ноль-дохуя, а за ним повторить 'def' ровно один раз.
как видишь, для «повторить ровно один раз» никакого спецсинтаксиса нет, но технически это всё та же операция повторения.
сопоставление с регуляркой обычно делается (логически) так, чтобы получилось как можно большее количество повторений первого «вариантивного» паттерна, потом на остатке — второго и так далее. это называется «жадные регулярки» — потому что они стараются по-максимуму «наповторяться».
фактически, ты на этом месте ты уже знаешь почти всё, что надо знать. осталась ещё одна операция: «альтернатива». что делать, если нам надо заебенить выбор: «или 'a', или 'b'»? тогда мы так и пишем: «a|b».
тут опять есть нюанс: '|' является символом-разделителем обзазцов (как и любой небуквенноцифровой символ). поэтому запрос: «начинается с 'a' или 'b', потом много 'fuck'» будет выглядеть так: (a|b)fuck*
ура, мы узнали, что в регулярках можно использовать скобки для группировки — прямо как в математике или… программировании! а заодно почти все движки позволяют по номеру скобок извлечь то, что они реально отматчили. то есть, я могу спросить у движка: «какую точно строку отматчили первые скобки выражения?»
ну вот, этого уже почти достаточно, чтобы применять регулярки для парзинга регулярных же строк. остались мелочи синтаксиса типа «а как написать пробел?» обычно — вот так: «\s». старые добрые «искейпы», только немного расширеные. ах, да: искейп считается «буквоцифрой», и не является разделителем обзазцов.
вот с этой базы ты можешь без труда начать плясать самостоятельно — остался там всякий синтаксический сахар.
6/17/18, 01:37 am
БЛЯБЛЯБЛЯ! Вот иди ты уже в пигидий в преподы, пожалуйста. "Даже я понял",попробовать потренероваться осталось.
6/17/18, 02:05 am
в интернетах есть сайты, которые позволяют сразу вводить паттерн и строки, и рисуют результаты. там чистый жабоскрип, оно несложно — но обычно удобно для «набивания руки». синтаксис регулярок везде очень похожий — они все из одного корня растут.
я, конечно, кучу нюансов не упомянул — но это действительно фигня. в смысле — когда ты грок основу, то будет уже несложно обмазаться дополнительным сахаром. типа char ranges, repetition counts, etc.
ах, да, чтобы ты не искал: точка в регулярке обозначает «any char». ;-) а поскольку точка не буква, то «ab.*c» обозначает: «ab» один раз, любой символ любое количество раз, «c» один раз — по правилу разделения образцов.
6/17/18, 02:09 am
и да, я спиздел, извини: искейп СЧИТАЕТСЯ буквоцифрой, и ЯВЛЯЕТСЯ разделителем. так же, как и точка, например.
6/17/18, 02:14 am
а, и ещё нюанс, на который часто попадают. регулярка (a)* технически совершенно правильная, и отматчится правильно, но вот запрос «где там отматчились скобки» — смысла не имеет. потому что она разворачивается в бесконечную последовательность: (a)(a)(a)(a)(a)… все эти скобки имеют один и тот же «внутренний идентификатор», и бедный матчер просто не знает, какая из скобок тебя интересует. поэтому для подобных случаев делают так: ((a)*) и вот тут уже первые скобки присутствуют в развёрнутой последовательности ровно один раз, поэтому о них можно спрашивать.
6/17/18, 12:00 am
А еще заведи, наконец, вебмани или Киви. А то мы хотим тебе переслать, а не можем.
6/17/18, 12:18 am
увы. я понимаю, что надо это мне, а проблемы у вас, но только btc. впрочем, говорят, что с киви делается перевод на приват. но btc в любом случае лучше — он ещё и анонимный.
6/17/18, 12:55 am
Иначе не можем, Киви в ГОРФ не делает перевод в приват, потому что антисанкции. Так бы мы тебе, хоть потихоньку, но донатили, будь у тебя яндекс, киви, или вебмани, мы мимо бухгалтерии каждый день проходим, и че бы там тебе сотку не кинуть, а если парням сказать, то они все по сотке кидать могли бы. Тем более, на твоих советах весь завод работает.
6/17/18, 12:58 am
ты не поверишь, но я тоже не в рф, так что не заводить какие-то рф-сервисы не только зашквар, но ещё и бесполезно, гыг.
6/17/18, 01:05 am
придумаем, не сразу, но придумаем. Директор так и сказал - считать сотрудником, потому что твоя помощь в переходе серверов (промышленных) на Линукс, это уже круто! Кетмар, переезжай в Петрозаводск.
6/17/18, 01:07 am
>переезжай в Петрозаводск за что ты меня так ненавидишь? я же честно старался пояснить за регулярки попонятней! ;-)
6/17/18, 01:12 am
Наоборот, любдю! Не, это вообще. Ты для Димона, для меня и для минимум трех проектов, сделал настолько дохуя просто подсказав! Ты не писал бизнес-план, ты не подбирал сотрудников, но благодаря тебе, я подумал, почему бы не скачать слакварь плюс халявный софт для бухгалтерии, плюс поставить пару схем для контроля, которые используют Тоталь?
6/17/18, 01:20 am
спасибо, я рад, если помог. на корпорации (а также заводы и ты пы) мне похуй, я не с ними общаюсь, а с людьми. несмотря на мой hatred image, я действительно рад, когда кому-то помогает то, что я пишу.
6/17/18, 01:29 am
Я стараюсь не на кого не работать, но иногда получается так, что таки да (либо они пиздят мой контент, но поскольку он свободный - а и хер с ним, воду в городе отключают теперь не на три месяца, а на неделю)
6/17/18, 01:15 am
Тоталь, это в смысле исходники, написанные в корпорации Тоталь (нефтяная такая компания, друзья Хуйла еще)
6/17/18, 01:20 am
И у меня квартира, а я жду как с тобой поделиться, потому что ты мой учитель, и, наверное, самый лучший. Прямо ААЗ из "Корпорации МИФ" (Если б ААЗ существовал ИРЛ, то мы бы с ним любое Хуйло свернули).
6/17/18, 01:00 am
Вон, от windows-серверов перешли на linux, заодно нашли софт для бетономешалок (я кроме как в охоте и бетоне понимаю только в литературе), заодно заменили техпроцесс, где раньше надо было четыре чувака, теперь линукс старается.
6/17/18, 01:03 am
молодцы, чо. это я не в смысле «свысока по плечу похлопать», а просто радуюсь.
|