Тестирование на пользователях

В айти есть много шуток про тестирование на пользователях — когда недостаточно оттестированный или не тестируемый вовсе продукт передаётся в использование и ошибки правятся в реальном времени, по мере поступления их от пользователя.

Считается, что а) это плохо, б) это присуще исключительно айти.

Я не считаю, что это всегда плохо. Для домашних проектов это вообще, как правило, единственный путь — у меня много проектов, которые я делал в одиночку «на коленке» и выложил в общее пользование. Конечно там могут быть баги, я хоть и тестировал их, но не заморачивался прохождением всех сценариев.

Так что в пункте «а» есть много «но». А в прошлые выходные оказалось, что и пункт «б» не является абсолютной истиной.

История строительства: перед открытием цирк проверили на прочность, собрав 2,5 тыс. солдат внутренних войск в ночь с 4 на 5 ноября 1967 года — конструкция выдержала.
Тестирование зрительских мест казанского цирка солдатиками

Сфотографировал плакат, на котором рассказывается о нагрузочном тестировании зрительских места казанского цирка солдатами. Можно, конечно, возразить, что солдаты — не пользователи. Но, мне кажется, что это не совсем так.

Тот, кто профессионально занимается тестированием, от пользователя отличается одним фактором — ему платят за нахождение багов, это его работа, он от этого не страдает. Нагрузочное тестирование скамеек не является профессиональной деятельностью солдат, не думаю, что им за это заплатили и они пострадали бы, если бы «нашли баг» — если бы скамейки под ними провалились.

8 комментариев

Сломал себе график

За школьные каникулы расслабился — дочку не надо было водить на школьный автобус, поэтому вставал на полчаса позже. Потом ещё полирнул длинными выходными и совсем сломал себе график. Когда каникулы кончились, вставать стало гораздо сложнее. Мне, сове, утро и так даётся непросто, а такие колебания совсем вышибают из колеи.

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

2 комментария

«Виселица» в каталоге программ

Нашу с дочкой игру для «Флиппера Зеро» «Виселица» включили сегодня в каталог программ для этого устройства. А ещё она есть в одной из альтернативных прошивок — от разработчика с ником RogueMaster!

Кстати, я думаю, что Ева является самым молодым соавтором игры для «Флиппера» в мире.

Скриншот страницы коммитов в Git: заголовок «Commits», ветка main, дата 7 ноября 2023, коммит «Hangman game (#174)» от bolknote 4 часа назад, статус Verified, хеш de3ef60.
Сегодня приняли нашу с дочкой игру в каталог программ «Флиппера Зеро»

2 комментария

Сжатие инструкций для CFR[]

Выложил свою программу для перевода растра в инструкции для интерпретатора CFR[]. Написана, к слову, на «Гоу». Что-то давно я не программировал на этом языке, вот и решил смазать свежим опытом уже начавшие ржаветь знания.

Самая интересная часть там — про оптимизацию. Из-за наличия цикла для однократного повторения, в который можно что-то вкладывать, программу можно писать сильно по-разному. Можно прямолинейно — FFFFFFFFFFFFFF, а можно упаковать в цикл — [F[FFF]], станет чуть короче.

Пиксельный зелёный персонаж с красным ртом и синим воротником на чёрном фоне.
RR[CF][FF][CCC]CF[F[RRR]]FCC[FF]F[FRR]FFCC[FF][CC][F[RRR]]CC[FF]FF[FRR]F[CC][CF][CCC]CF[FC]C[F[RRR]][FF]FF[CCC][FRR][FCCFF[CCC]][F[RRR]][FF]FF[FRR][FF]FFF

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

Я реализовал довольно очевидную идею — делаем две переменные, одна указывает на начало инструкций, вторая — на середину. Вырезаем подстроку между двумя этими индексами, ищем её сразу за правым индексом, если находим, заменяем на вырезанное, оборачивая в цикл и начинаем сканировать заново. Если не находим, сдвигаем сначала правый указатель к началу, повторяем поиск, потом левый к центру, повторяем поиск. Естественно по ходу надо отбрасывать куски, где не сбалансированы скобки, это совсем просто.

Схематичные рисунки прямоугольников с координатами (0,0), (m,0), (0,m), (m,m) и стрелками, показывающими направления движения или изменения, включая диаграмму с осями и точкой 0,0.
Мои рассуждения на бумаге по порядку обхода картинки

Кроме того, у нас есть восемь вариантов обхода картинки — по двум направлениям из каждого угла, что, если нет симметрии, даёт восемь разных наборов инструкций, которые сжимаются по-разному. Я перебираю все восемь и вывожу самый короткий вариант.

При этом немного смещается координаты отрисовки картинки. Её можно было бы возвращать обратно, но зачем? Интерпретатор и так рисует в центре холста, так что сдвиг — это не принципиально, только размер кодирующей последовательности увеличится.

Оставить комментарий

Капитан Крюк

Закончили на днях читать книжку про Питера Пена и дочка решила нарисовать в 3Д крюк по мотивам. Если кто не читал или не помнит, в книжке есть капитан пиратов, у которого крюк вместо одной руки. В детстве это интригует, как я понимаю.

Интересно как быстро, в общем-то, она научилась собирать нужное из доступных в палитре примитивов. Села, раз-раз, уже готова модель для печати. Тут в качестве основы буквы «J» и «V», параллелепипед и молния, прикреплённая на конец крюка для остроты.

Бежевая 3D-печатная деталь U-образной формы на серой платформе Bambu Engineering Plate с инструкцией по очистке.
Капитан Крюк остался бы доволен скоростью изготовления

Оставить комментарий

Про кости и скелеты

Когда я говорю, что иногда езжу покопать в составе военно-патриотического отряда, почему-то первое, что спрашивают многие — находим ли мы человеческие кости, а второе — не страшно ли, когда их находишь.

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

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

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

А вы боитесь костей и скелетов? Это иррациональный страх или вы можете проследить какие-то его корни?

6 комментариев

«Кибердеревня»

Девять лет назад я заказал кастомный свитер в компании «Свитеррариум». Свитер жив у меня до сих пор, надеваю его в походы или в холода, чтобы погулять с собакой. Не продырявился, не растянулся, но немного потерял внешний вид, что немудрено за такой срок.

С тех пор я время от времени думал заказать у этой компании что-нибудь ещё, да всё никак не приходила удачная идея. Время от времени я натыкался на их рекламу, подписался на канал в «Телеграме», в общем поглядывал на то как у «Свитеррариума» дела.

Со временем владелец компании отошёл от заказных свитеров к более массовой продукции, но из готовых изделий меня тоже что-то ничего не цепляло.

Мужчина в свитере с надписью «ПЛАНЕТИА 2080» и бинарным кодом «10000001101», делает селфи в зеркало, держа смартфон.
Свитер, который носит Робогозин в сериале «Кибердеревня»

Пока сегодня у них канале не появилось объявление о распродаже свитеров с рисунком из сериала «Кибердеревня». Не то, чтобы я был большим фанатом этого сериала, но поглядываю. В основном из-за картинки, — хорошие спецэффекты и прикольные детали, есть что порассматривать.

В общем, меня зацепило, после работы поехал примерять — ехал целый час, пробки, но очень уж хотелось приобрести. Сел, как влитой, будто на меня делался.

Оставить комментарий

CFR[]

Прикольную штуку увидел на «Хабре» — минималистичный язык CFR[] для рисования картинок. Тамошнему народу не очень-то понравилось, а я люблю такое.

Синтаксис односимволный, C — циклическая смена цвета (доступно семь цветов), F — рисование со сдвигом по текущему направлению, R — смена направления на 45° по часовой стрелке и пара [ ], которая один раз повторяет вложенные инструкции.

Сетка 5x16 с синими и белыми ячейками, образующими вертикальные полосы и отдельные блоки на чёрном фоне.
RR[FCCF[CCC]]FFCCF[CCC][FCCFF[CCC]]FF[FRR]CCF[CCC][FCCFF[CCC]]FCCFF[CCC][FCCF[CCC]][F[RRR]][FFCCF[CCC]][FCCFF[CCC]]FCCF[CCC][FRR]CCF[CCC][FCCFF[CCC]]FCCFF[CCC][FCCF[CCC]][F[RRR]]CCF[CCC]FCCF[[CCC]FFCCF][CCC]FFCCF[CCC]FFF

Лучше всего таким способом рисовать какие-нибудь рекуррентные штуки, но мне было интересно побаловаться с растром. К сожалению, интерпретатор на вход берёт не более 256 инструкций, поэтому особо не разгонишься.

Состряпал небольшую программу, которой попереводил разные картинки в инструкции CFR[]. В ограничение до обидного мало что влезает, но небольшие надписи писать можно.

Оставить комментарий

Анафема за кофе

Изучал на досуге по письменным источникам историю слов «кофе» и «кофей», ни к каким выводам не пришёл, но нашёл любопытный документ. Старообрядцам, оказывается, когда-то грозила анафема за употребления чая и кофе. Причём за употребление кофе наказание было более чем в десять раза строже.

Открытая старинная рукопись с церковнославянским текстом, красными заглавными буквами и миниатюрой креста на левой странице; видны фрагменты «Книги Иова» и описания седмиц.
Сборник выписей и сказаний, старообрядческий, XVIII в

В переводе на современный язык текст выглядит так:

Книга Иоанна Зонара, глава 16, лист 70. Ещё кто посмеет пить чай, тот отлучается от самого Бога и будет тоже предан анафеме, а ещё тот, кто посмеет пить кофе, в том будет коварство и лукавство, в сердце того не будет Бога и он будет предан анафеме десятикратно.

Кстати, тут, кажется, есть игра слов «кофъ» («кофе») и «ковъ» («коварство»), но возможно я что-то не так понял.

Оставить комментарий

Тыквенный кальян

Прочитал тут хохму про тыквенный спас, который предлагается праздновать как альтернативу Хэллоуину. Название пришло из какого-то анекдота середины десятых, но сейчас чуть ли не всерьёз предлагается создать свою новую традицию вместо заморской.

Народ уже вовсю облюбовал Хеллоуин, а как уж он называется — дело десятое. Тема тыквы вполне нам близка и хорошо продаётся — вчера, например, пил тыквенный латте в кофейне.

Можно развивать и дальше. Русский писатель Николай Николаевич Каразин в повести девятнадцатого века подсказывает нам идею скрестить тыкву и кальян. Впрочем, я не курю, возможно в кальянных в тыквенный спас вовсю это курят, а я просто не в курсе.

Отрывок из текста с выделенной фразой «тыквенный кальян», описывающий мальчика в красной рубашонке, держащего кальян, и Султан-берды с тростью.
Николай Николаевич Каразин, повесть «В камышах»

2 комментария

Пилю «Виселицу»

Не то, чтобы я не понимал, что сообщество владельцев «Флиппера» относительно небольшое, всё же это очень специфический инструмент, но всё же не ожидал, что написанная за выходные игрушка удостоится такого внимания.

Только выложил её на «Гитхаб», как мне написал автор одной из популярных альтернативных прошивок, прислал патч, исправляющий некую ошибку и попросил английскую версию, — хочет включить игру в свою прошивку.

Оранжевый портативный терминал с экраном, на котором отображается игра «Виселица» на русском языке: слово «АГА» и алфавит с отмеченными буквами.
Вчера для «Флиппера» пришёл чехол из Китая, выглядит — супер!

Доброе слово и кошке приятно, поэтому вот уже несколько дней пилю поддержку других языков.

Для начала переделал сборку на другой инструментарий — ранее игра не собиралась через более распространённый uFBT, потому что мой код использовал кое-какие кишочки прошивки, а uFBT её не содержит. Такой переход поможет опубликовать игру в общем каталоге, но я с этим не спешу.

Для поддержки английского пришлось довольно много переделать, всё что осталось сейчас — вывести меню, наверное сегодня уже доделаю. Я замахнулся на конфигурируемую поддержку, по моей идее, можно будет очень просто добавить любой язык, для которого есть шрифт.

Скриншот терминала с кодом russian.bolk, содержащим числа, шестнадцатеричные значения и сообщения «Окей», «Вы выиграли!», «Вы проиграли!
Файл описания языка, пример для русского

В итоге, файл описания выглядит как текстовый файл, где первой строкой написано название словаря, ниже стоит цифра, показывающая сколько букв будет выведено в строке, при рисовании клавиатуры, ещё ниже — зазор между буквами в угадываемом слове в пикселях, потом цифра, про которую я расскажу дальше, ниже — шестнадцатеричные коды букв в кодировке UCS-2, ещё ниже — строки сообщений.

Если открыть словарь для английского языка обычным текстовым редактором, то внутри будет текст, с русским такой номер не пройдёт. Объясню почему.

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

Во-первых, я перешёл на другой генератор — встроенный вызов furi_hal_random_get() вместо обычного для Си random(). Друг, который в прошлом имел дело с микроконтроллёрами, сказал, что как правило лучше использовать то, что предлагает фреймворк — так быстрее.

Во-вторых, я переделал метод выбора случайного слова. Раньше я выбирал слово с линейной сложностью — генерировал номер строки и читал словарь, пока его не достигну. Переделал на константную — выбираю случайное смещение в файле и ищу следующее слово после него. Что дало теоретический положительный эффект — более длинные слова выбираются чаще.

В-третьих, почти в два раза сократил файл словаря. Любая русская буква занимает в распространённых юникодных кодировках два байта, но второй байт всегда одинаковый, его можно выкинуть. Если посмотреть на ряд, описывающий клавиши в моём файле, видно, что первая четвёрка всё время повторяется. То есть из кода русской буквы А — 0x0410 можно убрать 0x04 и оставить только 0x10, мы и так будем знать какую букву кодировать.

В словаре так и сделано. Поскольку внутри программы я храню различные состояния в виде массива, мне нужно знать минимальный получившийся код символа, чтобы вычитать его, преобразовывая код в смещение в массиве. Для русского языка минимальный код будет у буквы А — 0x10, как я показывал выше, то его и нужно записать в файл описания языка. Цифра 16 в нём — это и есть 0x10 в десятичной кодировке.

Надеюсь сегодня допишу всё что нужно и выложу новый вариант.

3 комментария

«Электричка»

В последние лет пятнадцать слово «электричка», в значении «электропоезд» постепенно исчезало из лексикона людей в моём круге общения. Я сам на электричке в последний раз ездил в 2002-м году, кажется. Забавно, что несколько лет назад слово вернулось, но теперь уже в другом качестве — так теперь называют электромобили.

9 комментариев

Цифровая диета

Заметил за собой одну проблему — чрезмерное увлечение листанием лент как будто выжигает во мне всю творческую энергию и непропорционально расходует время. В моём случае такой эффект имеют «Пикабу» и короткие истории «Ютуба», больше я нигде так не залипаю.

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

Стоит, по всей видимости, задуматься об упорядочивании потребления информационной нямки и сесть на какую-то цифровую диету. Последний год испытаний на себе показал, что такая незначительная, казалось бы, штука, сильно влияет на моё качество жизни.

7 комментариев

Написали с дочкой игру

После того как я обнаружил, что на «Флиппере Зеро» можно писать программы с поддержкой русского языка, никак не мог отделаться от желания написать что-нибудь посерьёзнее демонстрационного примера с использованием этой идеи.

Раздумывал недолго, выбрал для реализацию игру «Виселица» (некоторые знают её под названием «Балда»), в которую когда-то мы играли в детстве.

Правила там простые — один игрок загадывает слово и рисует чёрточки по количеству букв в нём. Второй пытается отгадать побуквенно. Если названная буква в слове есть, на бумаге рисуется позиция или позиции этих букв, если нет, то рисуется часть виселицы. Если виселица нарисована полностью, отгадывающий проиграл, если слово угадано раньше, — выиграл.

Пока программировал, подсела дочка, спросила чем я занимаюсь, я рассказал с примерами. Мы даже пару раз сыграли на бумаге, после чего вызвалась мне помочь нарисовать графику к игре.

Человек с кудрявыми волосами работает за ноутбуком, на экране которого отображается оранжевый фон с пиксельным логотипом и надписью «РУБРИК».
Дочка рисует виселицу для нашей игры, это первый вариант, в игру не вошёл

Я подумал, что вполне смогу использовать то, что она нарисует в прототипе, но получилось вполне симпатично и я оставил её графику как есть.

Так что у нас с дочкой теперь есть первая совместная игра — я программировал и разрабатывал интерфейс, она нарисовала виселицу и иконку приложения, а так же выступила первым тестером.

6 комментариев

Пишем на «Флиппере Зеро» по-русски ★

Вкратце: в русским текстом работать можно, но сложно, код лежит на «Гитхабе».

Не мог не обратить внимание, что несмотря на приличное количество русскоязычных авторов программ для «Флиппера Зеро» и российское происхождение устройства, в софте под него нигде не обнаружилось ни одной буквы по-русски.

Flipper Zero

Стало интересно — а есть ли вообще в устройстве поддержка русского языка? Сел вечерком за исходники прошивки и оказалось, что однозначного ответа на заданный вопрос нет. Частичная поддержка есть и её можно заставить работать, но она работает как будто по недосмотру — никто её не собирался делать, так случайно вышло.

На экране Flipper Zero отображается текст: «Привет, мир! Пишем по-русски на Флиппере Зеро. Евгений Степаницев, 2023». Устройство показано в оранжевом стиле на тёмном фоне.
Вывод русских букв (трансляция с экрана через оболочку qFlipper)

Сейчас расскажу, что я имею ввиду и постараюсь покороче, никто сейчас не любит длинные тексты.

Внутри «Флиппера» довольно много всякого АПИ для вывода текста, от незатейливого, выводящего строку в заданные координаты, до довольно навороченного, умеющего переносить и выравнивать текст. К сожалению, с русскими буквами оно работать не умеет.

Под капотом у этого АПИ — очень известная в своей нише библиотека U∞g2, у которой по историческим, видимо, причинам есть два набора функций для работы со строками. Одни принимают только однобайтовую кодировку ASCII, другие работают в Юникоде.

АПИ «Флиппера», к сожалению, использует функции, которые с Юникодом работать не умеют. К счастью, по какой-то случайности, упомянутое АПИ содержит два вызова, которые помогают решить эту проблему, правда придётся помучаться.

Первый из них — canvas_set_custom_u8g2_font.

Чтобы что-то написать русскими буквами, нужен шрифт, который их содержит. Стандартный вывод canvas_set_font позволяет выбрать один из нескольких шрифтов, ни одни из которых кириллицу не поддерживает. Тут и приходит на помощь canvas_set_custom_u8g2_font. Он позволяет выбрать произвольный шрифт пакета U∞g2, — внутри их целая куча и некоторые в названии содержат слово «cyrillic».

Вот как я это делаю:

#include <u8g2/u8g2_fonts.c>
// …
canvas_set_custom_u8g2_font(canvas, u8g2_font_haxrcorp4089_t_cyrillic);

Файл u8g2/u8g2_fonts.c внутри себя содержит шрифты в особом формате, можно открыть его прямо в текстовом виде и посмотреть как всё устроено.

Шрифт мы выбрали, теперь надо что-нибудь вывести. Тут на помощь приходит canvas_draw_glyph. «Под капотом» у него лежит u8g2_DrawGlyph, которая понимает символы Юникода почти без танцев с бубном. Думаю, это чистое везение — наверняка эта функция появилась сильно позднее, поэтому у неё нет двух вариантов для работы с разными кодировками.

Плохая новость в том, что строки в коде мы обычно пишем в кодировке UTF-8, а canvas_draw_glyph ожидает их в UCS-2. Но есть и хорошая новость — в прошивке доступно АПИ для перекодирования, как обычно, великолепно документированное на языке Си.

Но canvas_draw_glyph, как можно понять из названия, выводит только один символ. Как же вывести строку? Достаточно просто — надо вывести её посимвольно, сдвигая координату на ширину символа. Звучит просто, но как это сделать?

Тут нас ждёт очередная засада. Дело в том, что canvas_glyph_width, которая должна бы это делать, принимает на вход только char, при том, что нижележащая u8g2_GetGlyphWidth преспокойно работает с Юникодом.

Поэтому я сделал просто — выдрал реализацию u8g2_GetGlyphWidth себе в исходники. В итоге мякотка моего решения выглядит вот так:

void unicode_draw_utf8_str(Canvas* canvas, uint8_t x, uint8_t y, char* str) {
    FuriStringUTF8State state = FuriStringUTF8StateStarting;
    FuriStringUnicodeValue value = 0;

    for(; *str; str++) {
        furi_string_utf8_decode(*str, &state, &value);
        if(state == FuriStringUTF8StateError) furi_crash(NULL);

        if(state == FuriStringUTF8StateStarting) {
            canvas_draw_glyph(canvas, x, y, value);
            x += unicode_GetGlyphWidth(&canvas->fb, value);
        }
    }
}

Тут unicode_GetGlyphWidth — скопированная реализация u8g2_GetGlyphWidth, а furi_string_utf8_decode используется для кодирования UTF-8-строки в последовательные символы UCS-2.

2 комментария

Куртка с подогревом

Давным-давно, ещё до «ковида» купил себе на какой-то распродаже на «Алиэкспрессе» китайскую куртку с подогревом. Просто попробовать — есть ли от них польза.

К сожалению, китайские размеры — та ещё лотерея, не повезло — рукава оказались слишком короткими.

Поскольку куртка стоила каких-то смешных денег, я не стал заморачиваться с возвратом. Так она и лежала у меня несколько лет, пока не попалась на глаза при переезде. В этот раз мне пришло в голову, что можно отдать её в мастерскую, чтобы ей отпороли рукава, превратив в жилетку.

Тепловизионное изображение футболки на полу: максимальная температура 43,2°C в нижней части, 30,2°C в центре; фон — тёмный пол с текстурой.
Моя куртка, снятая камерой с тепловизором

Сказано — сделано!

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

Буду носить как обычную жилетку, хоть какой-то толк.

Оставить комментарий

Кхе-кхе

Как «испанка», мутировав, полностью растворилась в других заболеваниях, так и ослабевший Ковид уже никого всерьёз не беспокоит — в мире ходят какие-то там очередные штаммы, но на них уже никто не обращает внимания. Да и инфоповоды есть помощнее.

Интересно, что вокруг стало как-то много покашливающих людей — ничем, вроде, не болеющих, но потихоньку иногда кашляющих. Не припомню раньше такого. Виновата не осенняя погода — началось это, кажется, ещё летом.

Все, с кем я об этом говорил, предполагают, что это какая-то форма Ковида. Эти люди не доктора, но любопытно, что покашливающих заметили все и теория у всех одна и та же. Post hoc, ergo propter hoc. Знает ли кто-то что это на самом деле?

15 комментариев

Моя первая программа под Flipper Zero

Вчера вечером разобрался-таки с прокруткой экрана для «песни про пиво» под Флиппер Зеро и выложил всё в репозиторий.

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

Белый многофункциональный инструмент Flipper Zero с оранжевым экраном, на котором отображается текст песни «58 bottles of beer on the wall», и оранжевыми кнопками управления.

Второй способ больше подходит для многоэкранных приложений, поэтому его я не выбрал — для моих целей там слишком много мороки. Поэтому в этой части всё получилось достаточно просто:

void beer_render_callback(Canvas* canvas, void* ctx) {
    // …
    elements_scrollbar(canvas, BEER_MAX - pos, BEER_MAX + 1);
    // …
}

int32_t beer_main(void* p) {
    // …
    switch (event.key) {
        case InputKeyDown:
            if (app->pos > 0) app->pos--;
            break;

        case InputKeyUp:
            if (app->pos < BEER_MAX) app->pos++;
            break;

        default:
            break;
    }

    view_port_update(app->view_port);
    // …
}

В цикле опроса клавиатуры ловим клавиши «вверх» и «вниз», в соответствии с клавишей увеличиваем или уменьшаем счётчик, после чего вызываем перерисовку, в коллбеке которой выводим экран и полосу прокрутки с правильной позицией.

Возможно сделаю ещё автоскроллинг экрана на длинное нажатие клавиши, но пока не уверен, что мне хочется — может лучше за что-нибудь более серьёзное сесть.

2 комментария

Программирую под Flipper Zero

Мне месяц назад на день рождения подарили «Флиппер Зеро» — «перочинный ножик для хакера». Довольно известное в узких кругах устройство, очень занятное. Но об этом как-нибудь в другой раз.

Давно подмывало что-нибудь под него написать, но всё как-то занят по уши был всякими неотложными делами — то сериалы надо посмотреть, то ленту в соцсетях полистать. Но наконец освободился, сегодня утром начал.

Белый многофункциональный инструмент Flipper Zero с оранжевым экраном, на котором написано «99 bottles of beer on the wall», лежит на деревянной поверхности.
Попробую написать «Песню о пиве»

В интернете есть несколько статей о том как начать, которые мне очень помогли. Довольно быстро я научился собирать первое приложение, которые выводит строчку текста и опрашивает клавиатуру. По пути поразился сколько бойлерплейта (шаблонного почти одинакового для каждого приложения кода) пришлось написать. Очень не хватает какого-нибудь фреймворка.

Пока застопорился — не пойму как прокручивать экран и есть ли что-то вообще для этого. Исчерпывающей документации по АПИ я что-то не нашёл, а в статьях сторонних разработчиков рекомендуют читать исходники других программ. Что ж, уже начал, но пока решение мне не попалось.

4 комментария

Железный лом

Месяц назад рассказал в одной компании о том, что в некоторых районах Татарстана люди промышляют добычей чёрного металла из земли. Ходят с металлоискателями, иногда даже самодельными, выкапывают всякое и сдают в пункты приёма металлолома.

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

В общем, пришлось к слову, рассказал, а в ответ меня огорошили тем, что килограмм металла стоит меньше двадцати рублей. Я тогда в первый раз всерьёз задумался о том сколько именно металла надо проволочь, чтобы хотя бы окупить бензин.

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

Сегодня опять об этом вспомнил.

Гуляя с собакой я обычно прохожу мимо кустарного забора, сделанного из старых металлических спинок кроватей, залитых цементом. А сегодня обратил внимание, что кто-то срезал выступающие из цемента металлические части. Столько усилий из-за десяти килограмм железа, — если продать, хватит на полторы чашки кофе.

9 комментариев