Значки Icons8, окно «О программе» с указанием авторства
Значки заменены на присланные. Они вшиты в программу модулем uIconData, который собирается из icons_online командой tools/make_icons.py — правятся исходные картинки, а не он. Размер выбран под кнопку: двадцать четыре точки в клетке двадцать восемь, уменьшение делает convert, пропорции сохранены — все исходники квадратные. Цвет значку задаётся при отрисовке: берётся прозрачность точки, а цвет — тот, каким сейчас рисуется кнопка. Поэтому один значок годится и для тёмной кнопки, и для оранжевой, и для недоступной. Перекрашенные запоминаются: цветов ровно три. Значок программы стал значком окна. Значок самого файла под Windows задаётся не отсюда, а ресурсом при сборке — это осталось как было. Окно «О программе» (Справка → О программе). Две вкладки: «Библиотеки и авторство» и «Что умеет». Первая обязательна — бесплатная лицензия Icons8 требует ссылку на каждый значок; заодно там перечислено всё, на чём программа держится, и под какой лицензией. Списки разные по системам: под Linux ffmpeg и libmpv ставит пакетный менеджер, под Windows их скачивает сама программа, и это разные сборки. Вкладки свои, а не TPageControl: системные вкладки под Windows остались бы светлой полосой поверх тёмного окна. Текст показывается нашим журналом — его можно выделить и скопировать, так что ссылку из списка получится взять в браузер. Перенос по словам свой: ссылки не рвутся, отступ списка сохраняется на продолжениях. Свои рисованные значки из icons/ убраны: они больше не используются, и держать рядом два набора значило бы путать.
BIN
icons/log.png
|
Before Width: | Height: | Size: 482 B |
|
|
@ -1,11 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
<!-- Журнал: полоса с сообщениями. Строки разной длины, как настоящий
|
||||
текст: одинаковые читались бы как таблица. -->
|
||||
<rect x="2" y="3" width="20" height="18" fill="none"
|
||||
stroke="currentColor" stroke-width="2"/>
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="square">
|
||||
<line x1="6" y1="8" x2="18" y2="8"/>
|
||||
<line x1="6" y1="12" x2="18" y2="12"/>
|
||||
<line x1="6" y1="16" x2="13" y2="16"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 612 B |
BIN
icons/ripple.png
|
Before Width: | Height: | Size: 589 B |
|
|
@ -1,9 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
<!-- Схлопывание: дыра между кусками закрывается, правый кусок
|
||||
переезжает влево. Пунктир — то место, которое исчезнет. -->
|
||||
<rect x="1" y="7" width="7" height="10" fill="currentColor"/>
|
||||
<rect x="16" y="7" width="7" height="10" fill="currentColor"/>
|
||||
<line x1="9" y1="12" x2="15" y2="12" stroke="currentColor"
|
||||
stroke-width="2" stroke-dasharray="2 2"/>
|
||||
<polygon points="10,12 15,8 15,16" fill="currentColor"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 617 B |
BIN
icons/snap.png
|
Before Width: | Height: | Size: 783 B |
|
|
@ -1,8 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
<!-- Прилипание: подкова магнита. Полюса внизу закрашены сплошным —
|
||||
так подкова не читается как перевёрнутая буква U. -->
|
||||
<path d="M5 19 V13 a7 7 0 0 1 14 0 V19" fill="none"
|
||||
stroke="currentColor" stroke-width="4"/>
|
||||
<rect x="3" y="18" width="4" height="4" fill="currentColor"/>
|
||||
<rect x="17" y="18" width="4" height="4" fill="currentColor"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 548 B |
4
icons_online/attribution.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Log panel: <a target="_blank" href="https://icons8.com/icon/79872/property">Property</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a>
|
||||
Ripple gaps: <a target="_blank" href="https://icons8.com/icon/2EQegp8tbR6Q/merge-vertical">Merge Vertical</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a>
|
||||
Magnet: <a target="_blank" href="https://icons8.com/icon/79942/magnet">Magnet</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a>
|
||||
App icon: <a target="_blank" href="https://icons8.com/icon/69093/showing-video-frames">Showing Video Frames</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a>
|
||||
BIN
icons_online/icons8-merge-vertical-64.png
Normal file
|
After Width: | Height: | Size: 463 B |
BIN
icons_online/icons8-property-30.png
Normal file
|
After Width: | Height: | Size: 190 B |
BIN
icons_online/icons8-магнит-30.png
Normal file
|
After Width: | Height: | Size: 291 B |
BIN
icons_online/icons8-объединение-по-вертикали-30.png
Normal file
|
After Width: | Height: | Size: 228 B |
BIN
icons_online/icons8-показ-видеокадров-30.png
Normal file
|
After Width: | Height: | Size: 183 B |
347
src/uAboutForm.pas
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
{
|
||||
uAboutForm — окно «О программе».
|
||||
|
||||
Две вкладки. Первая обязательна: значки взяты у Icons8, а их бесплатная
|
||||
лицензия требует указать авторство со ссылкой на каждый значок. Заодно
|
||||
там же перечислено всё, на чём программа держится, и под какой лицензией
|
||||
оно раздаётся — под Windows и под Linux наборы разные.
|
||||
|
||||
Вторая вкладка отвечает на вопрос «что эта штука умеет», который иначе
|
||||
задают каждому новому человеку голосом.
|
||||
|
||||
Вкладки свои, а не TPageControl: системные вкладки рисует система, и под
|
||||
Windows они остались бы светлой полосой поверх тёмного окна — ровно то,
|
||||
из-за чего здесь уже переписаны кнопки, полосы прокрутки, журнал и меню.
|
||||
Две кнопки-переключателя и две панели делают то же самое и выглядят как
|
||||
остальная программа.
|
||||
|
||||
Текст показывается нашим журналом: он умеет прокрутку, выделение и
|
||||
копирование в буфер — ссылку из списка можно взять и открыть в браузере.
|
||||
}
|
||||
unit uAboutForm;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Controls, Forms, Graphics, StdCtrls, Dialogs,
|
||||
uTheme, uLogView;
|
||||
|
||||
{ Показывает окно. Возвращается, когда его закрыли. }
|
||||
procedure ShowAboutForm;
|
||||
|
||||
implementation
|
||||
|
||||
{ Перенос по словам.
|
||||
|
||||
Журнал строки не переносит: он показывает сообщения программы, где
|
||||
перенос сбил бы выравнивание. Здесь же текст сплошной, и без переноса
|
||||
абзац уезжает за правый край.
|
||||
|
||||
Ссылки не трогаются вовсе: разорванную пополам ссылку не собрать
|
||||
обратно. Отступ строки переносится на её продолжения — иначе список
|
||||
рассыпается.
|
||||
|
||||
Ширина считается в знаках, а шрифт у нас пропорциональный, поэтому
|
||||
строка выходит короче обещанного. Это лучше, чем длиннее: за правый край
|
||||
не уедет ничего. }
|
||||
function Wrap(const AText: string; AWidth: Integer): string;
|
||||
var
|
||||
Src: TStringList;
|
||||
I, Space, Indent: Integer;
|
||||
Line, Rest: string;
|
||||
begin
|
||||
Result := '';
|
||||
Src := TStringList.Create;
|
||||
try
|
||||
Src.Text := AText;
|
||||
for I := 0 to Src.Count - 1 do
|
||||
begin
|
||||
Rest := Src[I];
|
||||
|
||||
if (Rest = '') or (Length(Rest) <= AWidth) or (Pos('http', Rest) > 0) then
|
||||
begin
|
||||
Result := Result + Rest + LineEnding;
|
||||
Continue;
|
||||
end;
|
||||
|
||||
{ Отступ запоминается и повторяется на всех продолжениях. }
|
||||
Indent := 0;
|
||||
while (Indent < Length(Rest)) and (Rest[Indent + 1] = ' ') do
|
||||
Inc(Indent);
|
||||
|
||||
while Length(Rest) > AWidth do
|
||||
begin
|
||||
{ Ищем последний пробел в пределах ширины; не нашли — рвём по
|
||||
ширине, иначе одно длинное слово повесило бы разбор. }
|
||||
Space := AWidth;
|
||||
while (Space > Indent + 1) and (Rest[Space] <> ' ') do
|
||||
Dec(Space);
|
||||
if Space <= Indent + 1 then
|
||||
Space := AWidth;
|
||||
Line := Copy(Rest, 1, Space);
|
||||
Rest := StringOfChar(' ', Indent) + Copy(Rest, Space + 1, Length(Rest));
|
||||
Result := Result + TrimRight(Line) + LineEnding;
|
||||
end;
|
||||
Result := Result + Rest + LineEnding;
|
||||
end;
|
||||
finally
|
||||
Src.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
{ Обработчики живут в объекте: событиям нужны методы. }
|
||||
TAboutDialog = class(TComponent)
|
||||
public
|
||||
Form: TForm;
|
||||
BtnCredits: TThemedButton;
|
||||
BtnFeatures: TThemedButton;
|
||||
ViewCredits: TLogView;
|
||||
ViewFeatures: TLogView;
|
||||
procedure ShowCredits(Sender: TObject);
|
||||
procedure ShowFeatures(Sender: TObject);
|
||||
procedure Select(ACredits: Boolean);
|
||||
end;
|
||||
|
||||
procedure TAboutDialog.Select(ACredits: Boolean);
|
||||
begin
|
||||
BtnCredits.Down := ACredits;
|
||||
BtnFeatures.Down := not ACredits;
|
||||
ViewCredits.Visible := ACredits;
|
||||
ViewFeatures.Visible := not ACredits;
|
||||
end;
|
||||
|
||||
procedure TAboutDialog.ShowCredits(Sender: TObject);
|
||||
begin
|
||||
Select(True);
|
||||
end;
|
||||
|
||||
procedure TAboutDialog.ShowFeatures(Sender: TObject);
|
||||
begin
|
||||
Select(False);
|
||||
end;
|
||||
|
||||
{ Кто это написал и на чём оно держится.
|
||||
|
||||
Списки разные по системам не для красоты: под Linux ffmpeg и libmpv
|
||||
ставит пакетный менеджер, под Windows их скачивает сама программа из
|
||||
окна «Зависимости», и это разные сборки с разными лицензиями. Указывать
|
||||
надо то, что стоит у человека, а не то, что бывает вообще. }
|
||||
function CreditsText: string;
|
||||
begin
|
||||
Result :=
|
||||
'nlve — монтаж без перекодирования' + LineEnding +
|
||||
LineEnding +
|
||||
'Автор: 4aiman' + LineEnding +
|
||||
LineEnding +
|
||||
'Замысел в одном: куски видео вырезаются и склеиваются копированием ' +
|
||||
'потока, без пересчёта картинки. То, что обычный монтажный редактор ' +
|
||||
'считает часами, здесь собирается за время копирования файла. ' +
|
||||
'Пересобирается только то, что иначе никак: переходы, прозрачность, ' +
|
||||
'точные резы и куски файлов с чужими параметрами.' + LineEnding +
|
||||
LineEnding +
|
||||
'── Значки ──' + LineEnding +
|
||||
LineEnding +
|
||||
'Значки взяты у Icons8 и требуют указания авторства.' + LineEnding +
|
||||
LineEnding +
|
||||
'Прилипание — значок «Magnet» от Icons8:' + LineEnding +
|
||||
' https://icons8.com/icon/79942/magnet' + LineEnding +
|
||||
'Схлопывание — значок «Merge Vertical» от Icons8:' + LineEnding +
|
||||
' https://icons8.com/icon/2EQegp8tbR6Q/merge-vertical' + LineEnding +
|
||||
'Журнал — значок «Property» от Icons8:' + LineEnding +
|
||||
' https://icons8.com/icon/79872/property' + LineEnding +
|
||||
'Значок программы — «Showing Video Frames» от Icons8:' + LineEnding +
|
||||
' https://icons8.com/icon/69093/showing-video-frames' + LineEnding +
|
||||
LineEnding +
|
||||
'Сам Icons8: https://icons8.com' + LineEnding +
|
||||
LineEnding +
|
||||
'── Чем режется и что показывает ──' + LineEnding +
|
||||
LineEnding +
|
||||
{$IFDEF WINDOWS}
|
||||
'ffmpeg и ffprobe — вся работа с видео и звуком: нарезка, склейка, ' +
|
||||
'перекодирование, разбор файлов.' + LineEnding +
|
||||
' Сборка BtbN, вариант gpl:' + LineEnding +
|
||||
' https://github.com/BtbN/FFmpeg-Builds' + LineEnding +
|
||||
' Лицензия сборки: GPL-3.0' + LineEnding +
|
||||
' Сам ffmpeg: https://ffmpeg.org' + LineEnding +
|
||||
LineEnding +
|
||||
'libmpv — предпросмотр монтажа. Играет виртуальный список кусков, ' +
|
||||
'не собирая при этом ни одного файла.' + LineEnding +
|
||||
' Сборка shinchiro/mpv-winbuild-cmake:' + LineEnding +
|
||||
' https://github.com/shinchiro/mpv-winbuild-cmake' + LineEnding +
|
||||
' Лицензия сборки: GPL' + LineEnding +
|
||||
' Сам mpv: https://mpv.io' + LineEnding +
|
||||
LineEnding +
|
||||
'7-Zip (7zr.exe) — распаковка сборок libmpv, они раздаются в .7z.' +
|
||||
LineEnding +
|
||||
' https://www.7-zip.org' + LineEnding +
|
||||
' Лицензия: LGPL-2.1' + LineEnding +
|
||||
{$ELSE}
|
||||
'ffmpeg и ffprobe — вся работа с видео и звуком: нарезка, склейка, ' +
|
||||
'перекодирование, разбор файлов.' + LineEnding +
|
||||
' Ставится пакетным менеджером: sudo apt install ffmpeg' + LineEnding +
|
||||
' https://ffmpeg.org' + LineEnding +
|
||||
' Лицензия сборок в Ubuntu: GPL-2 и новее' + LineEnding +
|
||||
LineEnding +
|
||||
'libmpv — предпросмотр монтажа. Играет виртуальный список кусков, ' +
|
||||
'не собирая при этом ни одного файла.' + LineEnding +
|
||||
' Ставится пакетным менеджером: sudo apt install mpv' + LineEnding +
|
||||
' https://mpv.io' + LineEnding +
|
||||
' Лицензия сборок в Ubuntu: GPL-3 и новее' + LineEnding +
|
||||
{$ENDIF}
|
||||
LineEnding +
|
||||
'── На чём написано ──' + LineEnding +
|
||||
LineEnding +
|
||||
'Free Pascal — компилятор.' + LineEnding +
|
||||
' https://www.freepascal.org' + LineEnding +
|
||||
' Лицензия: GPL с оговоркой о компоновке для библиотеки времени ' +
|
||||
'выполнения' + LineEnding +
|
||||
LineEnding +
|
||||
'Lazarus LCL — библиотека окон и элементов управления.' + LineEnding +
|
||||
' https://www.lazarus-ide.org' + LineEnding +
|
||||
' Лицензия: LGPL-2 с оговоркой о компоновке' + LineEnding +
|
||||
LineEnding +
|
||||
'Ни ffmpeg, ни libmpv в состав программы не входят и вместе с ней не ' +
|
||||
'раздаются: ffmpeg запускается отдельной программой, libmpv ' +
|
||||
'подключается на ходу и ставится отдельно.';
|
||||
end;
|
||||
|
||||
{ Что программа умеет. Не список кнопок, а список того, ради чего её
|
||||
открывают. }
|
||||
function FeaturesText: string;
|
||||
begin
|
||||
Result :=
|
||||
'Монтаж' + LineEnding +
|
||||
LineEnding +
|
||||
' Дорожки для картинки и для звука, сколько нужно. При перекрытии ' +
|
||||
'картинку даёт верхняя дорожка целиком, а звук всех дорожек ' +
|
||||
'смешивается: под голос кладётся музыка.' + LineEnding +
|
||||
' Клипы переносятся, растягиваются за края, режутся по курсору ' +
|
||||
'(S) и удаляются. Прилипание к краям соседей и к курсору; Shift во ' +
|
||||
'время перетаскивания отменяет его.' + LineEnding +
|
||||
' Связки: видео и его звук ходят вместе, Ctrl+G связывает и ' +
|
||||
'развязывает. Развязанный звук двигается отдельно от своей картинки.' +
|
||||
LineEnding +
|
||||
' Схлопывание дыр: вручную (Ctrl+Shift+R) или само при ' +
|
||||
'перетаскивании, на текущей дорожке или на всех сразу.' + LineEnding +
|
||||
' Отмена и повтор любого действия.' + LineEnding +
|
||||
LineEnding +
|
||||
'Что видно на дорожках' + LineEnding +
|
||||
LineEnding +
|
||||
' Форма звука на звуковых клипах; Shift со стрелками вверх и вниз ' +
|
||||
'усиливает её, когда запись тихая.' + LineEnding +
|
||||
' Громкость клипа — ручкой прямо на нём, прозрачность — так же на ' +
|
||||
'видеоклипе.' + LineEnding +
|
||||
' Появление и уход — за верхние углы клипа. Перекрытие двух клипов ' +
|
||||
'одной дорожки помечено косым крестом: там сам собой выходит переход.' +
|
||||
LineEnding +
|
||||
' Цвет краёв показывает, притянут рез к опорному кадру или потребует ' +
|
||||
'перекодирования.' + LineEnding +
|
||||
LineEnding +
|
||||
'Предпросмотр' + LineEnding +
|
||||
LineEnding +
|
||||
' Играет монтаж целиком, не собирая ни одного файла: плееру ' +
|
||||
'скармливается виртуальный список кусков.' + LineEnding +
|
||||
' Показывает кадр проекта, а не кадр очередного исходника — что ' +
|
||||
'видно здесь, то и получится в ролике.' + LineEnding +
|
||||
' Участки с прозрачностью и переходами заранее сводятся в отдельные ' +
|
||||
'файлы, поэтому видны и они.' + LineEnding +
|
||||
LineEnding +
|
||||
'Кадрирование' + LineEnding +
|
||||
LineEnding +
|
||||
' У каждого клипа своё: вписать целиком, заполнить кадр с обрезкой ' +
|
||||
'или растянуть. Плюс увеличение, смещение, поворот и отражение.' +
|
||||
LineEnding +
|
||||
' Рамку в окне кадрирования можно тянуть мышью, а не только задавать ' +
|
||||
'числами.' + LineEnding +
|
||||
LineEnding +
|
||||
'Сборка ролика' + LineEnding +
|
||||
LineEnding +
|
||||
' Обычная — копированием потоков. Час материала собирается за время ' +
|
||||
'копирования файла.' + LineEnding +
|
||||
' Перед сборкой программа говорит, сколько секунд придётся ' +
|
||||
'пересобрать и почему.' + LineEnding +
|
||||
' Точный рез перекодирует только огрызок до ближайшего опорного ' +
|
||||
'кадра, остальное копируется.' + LineEnding +
|
||||
' Отдельно — сборка с перекодированием: размер кадра от 720p до 4K, ' +
|
||||
'поток в килобитах, кодек HEVC или H.264. Считает видеокарта.' +
|
||||
LineEnding +
|
||||
' Перепаковка готовых файлов в другой контейнер, без пересчёта.' +
|
||||
LineEnding +
|
||||
LineEnding +
|
||||
'Мелочи, которые важны' + LineEnding +
|
||||
LineEnding +
|
||||
' Индекс опорных кадров читается из заголовка файла, а не ' +
|
||||
'перебором: на шестигигабайтном файле это двадцать миллисекунд ' +
|
||||
'вместо двенадцати секунд.' + LineEnding +
|
||||
' Фоновая работа видна внизу полоской и отмечена на монтаже ' +
|
||||
'штриховкой.' + LineEnding +
|
||||
' Все окна в своих цветах, а не в системных.' + LineEnding +
|
||||
' Настройки, недавние проекты и размеры окна переживают перезапуск.';
|
||||
end;
|
||||
|
||||
procedure ShowAboutForm;
|
||||
var
|
||||
Dlg: TAboutDialog;
|
||||
BtnClose: TThemedButton;
|
||||
begin
|
||||
Dlg := TAboutDialog.Create(nil);
|
||||
try
|
||||
Dlg.Form := TForm.CreateNew(nil);
|
||||
Dlg.Form.Caption := 'О программе';
|
||||
Dlg.Form.Position := poScreenCenter;
|
||||
Dlg.Form.ClientWidth := 720;
|
||||
Dlg.Form.ClientHeight := 560;
|
||||
Dlg.Form.Constraints.MinWidth := 480;
|
||||
Dlg.Form.Constraints.MinHeight := 320;
|
||||
|
||||
Dlg.BtnCredits := TThemedButton.Create(Dlg.Form);
|
||||
Dlg.BtnCredits.Parent := Dlg.Form;
|
||||
Dlg.BtnCredits.SetBounds(12, 12, 240, 28);
|
||||
Dlg.BtnCredits.Caption := 'Библиотеки и авторство';
|
||||
Dlg.BtnCredits.TabStop := False;
|
||||
Dlg.BtnCredits.OnClick := @Dlg.ShowCredits;
|
||||
|
||||
Dlg.BtnFeatures := TThemedButton.Create(Dlg.Form);
|
||||
Dlg.BtnFeatures.Parent := Dlg.Form;
|
||||
Dlg.BtnFeatures.SetBounds(258, 12, 180, 28);
|
||||
Dlg.BtnFeatures.Caption := 'Что умеет';
|
||||
Dlg.BtnFeatures.TabStop := False;
|
||||
Dlg.BtnFeatures.OnClick := @Dlg.ShowFeatures;
|
||||
|
||||
Dlg.ViewCredits := TLogView.Create(Dlg.Form);
|
||||
Dlg.ViewCredits.Parent := Dlg.Form;
|
||||
Dlg.ViewCredits.SetBounds(12, 48, 696, 460);
|
||||
Dlg.ViewCredits.Anchors := [akTop, akLeft, akRight, akBottom];
|
||||
{ Ширина подобрана замером: при 720 точках окна в строку входит около
|
||||
ста шестидесяти знаков, берём с запасом. }
|
||||
Dlg.ViewCredits.SetText(Wrap(CreditsText, 150));
|
||||
|
||||
Dlg.ViewFeatures := TLogView.Create(Dlg.Form);
|
||||
Dlg.ViewFeatures.Parent := Dlg.Form;
|
||||
Dlg.ViewFeatures.SetBounds(12, 48, 696, 460);
|
||||
Dlg.ViewFeatures.Anchors := [akTop, akLeft, akRight, akBottom];
|
||||
Dlg.ViewFeatures.SetText(Wrap(FeaturesText, 150));
|
||||
|
||||
BtnClose := TThemedButton.Create(Dlg.Form);
|
||||
BtnClose.Parent := Dlg.Form;
|
||||
BtnClose.SetBounds(608, 520, 100, 28);
|
||||
BtnClose.Anchors := [akRight, akBottom];
|
||||
BtnClose.Caption := 'Закрыть';
|
||||
BtnClose.ModalResult := mrOk;
|
||||
BtnClose.Default := True;
|
||||
BtnClose.Cancel := True;
|
||||
|
||||
ApplyDarkTheme(Dlg.Form);
|
||||
{ Значок окна берётся у главного окна: своего у диалога нет. }
|
||||
Dlg.Select(True);
|
||||
Dlg.Form.ShowModal;
|
||||
finally
|
||||
Dlg.Form.Free;
|
||||
Dlg.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
398
src/uIconData.pas
Normal file
|
|
@ -0,0 +1,398 @@
|
|||
{
|
||||
uIconData — значки, вшитые в программу.
|
||||
|
||||
Собран из файлов в icons_online командой:
|
||||
|
||||
python3 tools/make_icons.py
|
||||
|
||||
Правится не он, а исходные картинки: этот файл переписывается целиком.
|
||||
|
||||
Значки взяты у Icons8 и требуют указания авторства — оно есть в окне
|
||||
«О программе», вкладка «Библиотеки и авторство». Ссылки на каждый значок
|
||||
лежат в icons_online/attribution.txt.
|
||||
|
||||
Картинки чёрные на прозрачном фоне. Цвет им задаётся при отрисовке:
|
||||
берётся прозрачность точки, а цвет — тот, каким сейчас рисуется кнопка.
|
||||
Поэтому один и тот же значок годится и для тёмной кнопки, и для
|
||||
оранжевой.
|
||||
}
|
||||
unit uIconData;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
{ icons8-магнит-30.png, 24 на 24 точек }
|
||||
IconSnapData: array[0..472] of Byte = (
|
||||
$89, $50, $4E, $47, $0D, $0A, $1A, $0A, $00, $00, $00, $0D, $49, $48, $44, $52,
|
||||
$00, $00, $00, $18, $00, $00, $00, $18, $08, $04, $00, $00, $00, $4A, $7E, $F5,
|
||||
$73, $00, $00, $00, $20, $63, $48, $52, $4D, $00, $00, $7A, $26, $00, $00, $80,
|
||||
$84, $00, $00, $FA, $00, $00, $00, $80, $E8, $00, $00, $75, $30, $00, $00, $EA,
|
||||
$60, $00, $00, $3A, $98, $00, $00, $17, $70, $9C, $BA, $51, $3C, $00, $00, $00,
|
||||
$02, $62, $4B, $47, $44, $00, $00, $AA, $8D, $23, $32, $00, $00, $00, $09, $70,
|
||||
$48, $59, $73, $00, $00, $0B, $13, $00, $00, $0B, $13, $01, $00, $9A, $9C, $18,
|
||||
$00, $00, $00, $07, $74, $49, $4D, $45, $07, $EA, $08, $16, $07, $2D, $16, $EF,
|
||||
$B8, $28, $FD, $00, $00, $01, $3E, $49, $44, $41, $54, $38, $CB, $BD, $92, $31,
|
||||
$4B, $C3, $40, $14, $C7, $7F, $97, $44, $29, $68, $03, $5A, $45, $EA, $D0, $A5,
|
||||
$6B, $41, $44, $5C, $0A, $0E, $3A, $15, $DC, $1D, $DD, $FB, $51, $74, $71, $29,
|
||||
$F8, $39, $EC, $62, $06, $17, $5D, $EA, $22, $D2, $88, $93, $E0, $22, $68, $A1,
|
||||
$AD, $14, $AA, $A0, $B6, $E6, $39, $24, $17, $AE, $69, $32, $88, $D4, $77, $4B,
|
||||
$EE, $DD, $EF, $7F, $EF, $DD, $FB, $07, $66, $1D, $6A, $6A, $EF, $B2, $4D, $85,
|
||||
$22, $F3, $74, $B9, $E3, $9A, $1E, $92, $2D, $5F, $E0, $80, $0B, $9E, $78, $27,
|
||||
$40, $F8, $E4, $85, $4B, $0E, $71, $B3, $F0, $35, $4E, $78, $45, $12, $6B, $40,
|
||||
$83, $62, $1A, $BE, $44, $83, $AF, $29, $5C, $10, $46, $9C, $B2, $9C, $C4, $1D,
|
||||
$EA, $0C, $53, $71, $41, $78, $A3, $8E, $33, $29, $28, $E1, $67, $E2, $82, $E0,
|
||||
$53, $0A, $41, $2B, $9A, $CD, $1E, $65, $43, $3E, $C0, $C7, $67, $60, $64, $CA,
|
||||
$EC, $86, $13, $D5, $82, $2A, $B9, $F8, $B0, $C7, $11, $35, $6A, $1C, $D3, $8F,
|
||||
$73, $39, $AA, $A6, $05, $16, $9E, $51, $BE, $49, $01, $80, $02, $4D, $23, $EB,
|
||||
$85, $97, $EB, $0A, $E6, $AC, $3B, $D1, $CD, $7D, $3A, $46, $D6, $35, $5B, $9A,
|
||||
$74, $5C, $52, $BE, $62, $C2, $E2, $97, $31, $7B, $81, $F6, $4F, $F1, $41, $1B,
|
||||
$61, $8E, $AD, $04, $71, $C3, $08, $C5, $86, $7E, $83, $16, $D8, $DC, $B3, $C3,
|
||||
$37, $AB, $3C, $18, $03, $50, $0C, $D9, $A7, $8B, $4D, $0B, $FB, $8F, $2D, $8D,
|
||||
$D9, $A4, $85, $E0, $90, $27, $88, $4F, $03, $F2, $78, $8C, $51, $54, $B8, $D5,
|
||||
$AD, $84, $A5, $D7, $59, $C4, $02, $84, $47, $CE, $68, $47, $82, $02, $2B, $11,
|
||||
$F1, $CC, $39, $57, $88, $B6, $43, $A1, $8C, $CE, $83, $D8, $30, $65, $B4, $1C,
|
||||
$FE, $20, $FF, $10, $3F, $90, $74, $7D, $D8, $DF, $AB, $6B, $DD, $00, $00, $00,
|
||||
$00, $49, $45, $4E, $44, $AE, $42, $60, $82
|
||||
);
|
||||
|
||||
{ icons8-merge-vertical-64.png, 24 на 24 точек }
|
||||
IconRippleData: array[0..457] of Byte = (
|
||||
$89, $50, $4E, $47, $0D, $0A, $1A, $0A, $00, $00, $00, $0D, $49, $48, $44, $52,
|
||||
$00, $00, $00, $18, $00, $00, $00, $18, $08, $04, $00, $00, $00, $4A, $7E, $F5,
|
||||
$73, $00, $00, $00, $20, $63, $48, $52, $4D, $00, $00, $7A, $26, $00, $00, $80,
|
||||
$84, $00, $00, $FA, $00, $00, $00, $80, $E8, $00, $00, $75, $30, $00, $00, $EA,
|
||||
$60, $00, $00, $3A, $98, $00, $00, $17, $70, $9C, $BA, $51, $3C, $00, $00, $00,
|
||||
$02, $62, $4B, $47, $44, $00, $00, $AA, $8D, $23, $32, $00, $00, $00, $09, $70,
|
||||
$48, $59, $73, $00, $00, $0B, $13, $00, $00, $0B, $13, $01, $00, $9A, $9C, $18,
|
||||
$00, $00, $00, $07, $74, $49, $4D, $45, $07, $EA, $08, $16, $07, $2D, $16, $EF,
|
||||
$B8, $28, $FD, $00, $00, $01, $2F, $49, $44, $41, $54, $38, $CB, $CD, $D2, $3D,
|
||||
$2F, $83, $51, $18, $C6, $F1, $DF, $C3, $63, $31, $34, $11, $B5, $35, $D1, $A9,
|
||||
$C1, $E0, $25, $4C, $66, $49, $F9, $16, $24, $96, $C6, $37, $A8, $18, $7D, $02,
|
||||
$31, $98, $18, $99, $25, $44, $F8, $02, $26, $B1, $30, $30, $78, $D9, $90, $18,
|
||||
$24, $35, $F4, $B4, $8F, $A1, $8A, $7A, $5A, $D2, $45, $FC, $C7, $73, $DF, $D7,
|
||||
$7D, $AE, $EB, $3E, $87, $2E, $89, $52, $27, $3D, $7A, $50, $43, $2F, $EA, $EA,
|
||||
$BF, $8D, $28, $3A, $B6, $A9, $5F, $BF, $4D, $C7, $8A, $DF, $CB, $71, $4A, $90,
|
||||
$33, $27, $2B, $C6, $AC, $49, $BB, $69, $03, $5D, $F2, $77, $82, $A8, $CD, $BE,
|
||||
$BE, $F2, $51, $6F, $0A, $46, $2D, $E8, $EB, $D8, $1E, $2B, $1A, $69, $15, $0C,
|
||||
$DB, $B6, $66, $A8, $6D, $7B, $D6, $AA, $1D, $F9, $A6, $B6, $60, $40, $50, $90,
|
||||
$55, $36, $A3, $FC, $CD, $5A, $64, $C2, $BA, $79, $91, $82, $07, $B1, $67, $F6,
|
||||
$54, $BC, $78, $95, $48, $24, $AE, $1D, $49, $9C, $C9, $C8, $38, $93, $38, $74,
|
||||
$F5, $5E, $79, $F5, $A2, $62, $2F, $16, $54, $D5, $BE, $CC, $4C, $3A, $E4, $08,
|
||||
$AA, $EA, $02, $79, $E3, $C6, $94, $D4, $04, $07, $26, $2D, $B7, $DC, $B0, $6C,
|
||||
$C2, $BE, $A0, $A6, $64, $CC, $B8, $7C, $EC, $E6, $3D, $F4, $93, $2D, $1B, $1E,
|
||||
$4D, $B7, $CC, $4D, $9C, $5B, $B2, $A2, $E4, $C6, $45, $23, $74, $83, $5B, $8B,
|
||||
$4E, $54, $DB, $9A, $79, $B2, $EE, $D4, $5D, $73, $4B, $0D, $2E, $5D, $76, $74,
|
||||
$4F, $70, $F4, $F9, $24, $3F, $47, $4D, $AD, $E2, $1F, $FF, $D6, $4F, $AA, $2A,
|
||||
$EE, $05, $C1, $BD, $4A, $87, $BD, $B5, $30, $68, $4A, $4E, $24, $92, $33, $65,
|
||||
$B0, $5B, $07, $29, $DE, $00, $F6, $77, $56, $B3, $E2, $94, $4B, $80, $00, $00,
|
||||
$00, $00, $49, $45, $4E, $44, $AE, $42, $60, $82
|
||||
);
|
||||
|
||||
{ icons8-property-30.png, 24 на 24 точек }
|
||||
IconLogData: array[0..425] of Byte = (
|
||||
$89, $50, $4E, $47, $0D, $0A, $1A, $0A, $00, $00, $00, $0D, $49, $48, $44, $52,
|
||||
$00, $00, $00, $18, $00, $00, $00, $18, $08, $04, $00, $00, $00, $4A, $7E, $F5,
|
||||
$73, $00, $00, $00, $20, $63, $48, $52, $4D, $00, $00, $7A, $26, $00, $00, $80,
|
||||
$84, $00, $00, $FA, $00, $00, $00, $80, $E8, $00, $00, $75, $30, $00, $00, $EA,
|
||||
$60, $00, $00, $3A, $98, $00, $00, $17, $70, $9C, $BA, $51, $3C, $00, $00, $00,
|
||||
$02, $62, $4B, $47, $44, $00, $00, $AA, $8D, $23, $32, $00, $00, $00, $09, $70,
|
||||
$48, $59, $73, $00, $00, $0B, $13, $00, $00, $0B, $13, $01, $00, $9A, $9C, $18,
|
||||
$00, $00, $00, $07, $74, $49, $4D, $45, $07, $EA, $08, $16, $07, $2D, $16, $EF,
|
||||
$B8, $28, $FD, $00, $00, $01, $0F, $49, $44, $41, $54, $38, $CB, $B5, $D3, $BF,
|
||||
$2E, $83, $51, $18, $C7, $F1, $CF, $5B, $15, $0C, $74, $93, $88, $91, $0B, $E8,
|
||||
$68, $60, $33, $34, $B1, $1A, $F4, $1E, $0C, $66, $8B, $C5, $05, $B8, $01, $89,
|
||||
$2B, $30, $18, $24, $4C, $0D, $8B, $41, $13, $46, $62, $90, $18, $A4, $4B, $55,
|
||||
$3A, $28, $AD, $F7, $18, $AA, $F5, $36, $DA, $B7, $25, $3C, $67, $38, $27, $4F,
|
||||
$9E, $EF, $79, $FE, $9C, $F3, $E3, $BF, $2D, $42, $24, $12, $8D, $10, $1B, $04,
|
||||
$21, $8B, $39, $5B, $96, $65, $84, $D4, $8B, $63, $E7, $F6, $3C, $42, $51, $A3,
|
||||
$4D, $0F, $59, $2F, $36, $C8, $60, $C6, $C4, $48, $E5, $4F, $CA, $B5, $81, $1F,
|
||||
$59, $F6, $73, $7F, $D6, $1C, $12, $39, $2E, $97, $04, $8A, $2E, $BA, $E7, $7E,
|
||||
$D6, $B2, $E4, $38, $09, $D4, $3C, $0D, $C9, $50, $EB, $2D, $09, $F2, $0A, $0E,
|
||||
$B0, $69, $36, $E1, $6D, $3A, $72, $F2, $BD, $07, $98, $B7, $EA, $50, $B0, $66,
|
||||
$B1, $FB, $26, $91, $86, $DB, $41, $C0, $A9, $92, $86, $60, $A5, $67, $76, $C1,
|
||||
$5B, $BF, $29, $B5, $33, $E4, $95, $50, $90, $4B, $64, $68, $B9, $74, $DD, $1F,
|
||||
$C8, $DB, $76, $23, $D8, $B5, $90, $F0, $BE, $DA, $19, $04, $9C, $B9, $73, $8F,
|
||||
$75, $53, $09, $6F, $EC, $61, $50, $49, $55, $55, $70, $95, $36, $DD, $5F, $7F,
|
||||
$8D, $08, $63, $29, $71, $EF, $1D, $C5, $74, $80, $7D, $F5, $54, $11, $05, $D3,
|
||||
$5F, $40, $45, $59, $3C, $44, $73, $91, $BA, $B2, $4A, $47, $A2, $A3, $76, $12,
|
||||
$A7, $AA, $F2, $8F, $EC, $03, $0F, $C8, $51, $5A, $EC, $EA, $63, $7C, $00, $00,
|
||||
$00, $00, $49, $45, $4E, $44, $AE, $42, $60, $82
|
||||
);
|
||||
|
||||
{ icons8-показ-видеокадров-30.png, значок окна, 32 на 32 точек, формат ico }
|
||||
IconAppData: array[0..4285] of Byte = (
|
||||
$00, $00, $01, $00, $01, $00, $20, $20, $00, $00, $01, $00, $20, $00, $A8, $10,
|
||||
$00, $00, $16, $00, $00, $00, $28, $00, $00, $00, $20, $00, $00, $00, $40, $00,
|
||||
$00, $00, $01, $00, $20, $00, $00, $00, $00, $00, $00, $10, $00, $00, $13, $0B,
|
||||
$00, $00, $13, $0B, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $37, $00, $00, $00, $A1, $00, $00, $00, $BB, $00, $00,
|
||||
$00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00,
|
||||
$00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00,
|
||||
$00, $BB, $00, $00, $00, $A1, $00, $00, $00, $37, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $51, $00, $00, $00, $E5, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $E5, $00, $00, $00, $51, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $1E, $00, $00, $00, $58, $00, $00, $00, $66, $00, $00,
|
||||
$00, $66, $00, $00, $00, $66, $00, $00, $00, $66, $00, $00, $00, $66, $00, $00,
|
||||
$00, $66, $00, $00, $00, $66, $00, $00, $00, $66, $00, $00, $00, $66, $00, $00,
|
||||
$00, $66, $00, $00, $00, $58, $00, $00, $00, $1E, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $15, $00, $00,
|
||||
$00, $54, $00, $00, $00, $74, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00,
|
||||
$00, $77, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00,
|
||||
$00, $77, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00,
|
||||
$00, $77, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00,
|
||||
$00, $77, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00, $00, $77, $00, $00,
|
||||
$00, $77, $00, $00, $00, $77, $00, $00, $00, $74, $00, $00, $00, $54, $00, $00,
|
||||
$00, $15, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $69, $00, $00,
|
||||
$00, $DB, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $DA, $00, $00,
|
||||
$00, $68, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $BE, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $C7, $00, $00, $00, $A4, $00, $00, $00, $D7, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $D7, $00, $00, $00, $A4, $00, $00, $00, $C7, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $BD, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $55, $00, $00, $00, $00, $00, $00, $00, $88, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $88, $00, $00, $00, $00, $00, $00, $00, $55, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $79, $00, $00, $00, $29, $00, $00, $00, $A1, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $A1, $00, $00, $00, $29, $00, $00, $00, $79, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $EC, $00, $00, $00, $E1, $00, $00, $00, $F2, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $F2, $00, $00, $00, $E1, $00, $00, $00, $EC, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $5C, $00, $00, $00, $00, $00, $00, $00, $8D, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $8D, $00, $00, $00, $00, $00, $00, $00, $5C, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $5C, $00, $00, $00, $00, $00, $00, $00, $8D, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $8D, $00, $00, $00, $00, $00, $00, $00, $5C, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $EC, $00, $00, $00, $E1, $00, $00, $00, $F2, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $F2, $00, $00, $00, $E1, $00, $00, $00, $EC, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $79, $00, $00, $00, $29, $00, $00, $00, $A1, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $A1, $00, $00, $00, $29, $00, $00, $00, $79, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $55, $00, $00, $00, $00, $00, $00, $00, $88, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $88, $00, $00, $00, $00, $00, $00, $00, $55, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $C6, $00, $00, $00, $A4, $00, $00, $00, $D7, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $D7, $00, $00, $00, $A4, $00, $00, $00, $C6, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $A4, $00, $00, $00, $6E, $00, $00, $00, $C0, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C0, $00, $00, $00, $6E, $00, $00, $00, $A4, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C9, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $55, $00, $00, $00, $00, $00, $00, $00, $88, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $88, $00, $00, $00, $00, $00, $00, $00, $55, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C9, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $C3, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $99, $00, $00, $00, $5C, $00, $00, $00, $B8, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $B8, $00, $00, $00, $5C, $00, $00, $00, $99, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $C3, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $8A, $00, $00,
|
||||
$00, $EA, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00,
|
||||
$00, $FF, $00, $00, $00, $FF, $00, $00, $00, $FF, $00, $00, $00, $EA, $00, $00,
|
||||
$00, $89, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $26, $00, $00,
|
||||
$00, $87, $00, $00, $00, $B6, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00,
|
||||
$00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00,
|
||||
$00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00,
|
||||
$00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00,
|
||||
$00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00, $00, $BA, $00, $00,
|
||||
$00, $BA, $00, $00, $00, $BA, $00, $00, $00, $B6, $00, $00, $00, $86, $00, $00,
|
||||
$00, $24, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
|
||||
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $FF,
|
||||
$FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $80,
|
||||
$01, $FF, $FF, $80, $01, $FF, $FF, $80, $01, $FF, $FF, $FF, $FF, $FF, $E0, $00,
|
||||
$00, $07, $E0, $00, $00, $07, $E0, $00, $00, $07, $E2, $00, $00, $47, $E0, $00,
|
||||
$00, $07, $E0, $00, $00, $07, $E0, $00, $00, $07, $E2, $00, $00, $47, $E2, $00,
|
||||
$00, $47, $E0, $00, $00, $07, $E0, $00, $00, $07, $E0, $00, $00, $07, $E2, $00,
|
||||
$00, $47, $E0, $00, $00, $07, $E0, $00, $00, $07, $E0, $00, $00, $07, $E2, $00,
|
||||
$00, $47, $E0, $00, $00, $07, $E0, $00, $00, $07, $E0, $00, $00, $07, $FF, $FF,
|
||||
$FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
|
||||
);
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
@ -25,10 +25,11 @@ uses
|
|||
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
|
||||
ComCtrls, Menus, Buttons, LCLType, LMessages,
|
||||
uAppTypes, uEdl, uMpvLib, uMpvPlayer, uProject, uMediaProbe, uTimelineCtrl,
|
||||
uFlatten, uGenerate, uExport, uEncodeForm, uProgressForm, uRemuxForm,
|
||||
uMismatchForm,
|
||||
uFlatten, uGenerate, uExport, uEncodeForm, uAboutForm, uProgressForm,
|
||||
uRemuxForm, uMismatchForm,
|
||||
uFfmpegJob, uSettings, uThumbs, uTransform, uPanCropForm,
|
||||
uProjectInfoForm, ImgList, uTheme, uLogView, uDepsForm, uWaveform;
|
||||
uProjectInfoForm, ImgList, uTheme, uLogView, uDepsForm, uWaveform,
|
||||
uIconData;
|
||||
|
||||
const
|
||||
{ Номера системных сообщений о перерисовке рамки окна. Берём числами, а
|
||||
|
|
@ -207,11 +208,13 @@ type
|
|||
|
||||
{ --- окно и меню --- }
|
||||
procedure BuildMenu;
|
||||
procedure ApplyWindowIcon;
|
||||
procedure BuildJobIndicator;
|
||||
procedure JobTimerTick(Sender: TObject);
|
||||
procedure AdvanceJobBar;
|
||||
procedure LogButtonClick(Sender: TObject);
|
||||
procedure MenuToggleLog(Sender: TObject);
|
||||
procedure MenuAbout(Sender: TObject);
|
||||
procedure ApplyLogVisible(AVisible: Boolean);
|
||||
procedure BuildTimeline;
|
||||
procedure StartPlayer;
|
||||
|
|
@ -566,7 +569,7 @@ procedure TMainForm.BuildMenu;
|
|||
end;
|
||||
|
||||
var
|
||||
MFile, MEdit, MView, MProject: TMenuItem;
|
||||
MFile, MEdit, MView, MProject, MHelp: TMenuItem;
|
||||
begin
|
||||
{ Подсказки всплывают почти сразу: на кнопке со значком они не
|
||||
украшение, а единственный способ узнать, что она делает. Держатся
|
||||
|
|
@ -575,6 +578,8 @@ begin
|
|||
Application.HintPause := 100;
|
||||
Application.HintHidePause := 15000;
|
||||
|
||||
ApplyWindowIcon;
|
||||
|
||||
BuildJobIndicator;
|
||||
FMenu := TMainMenu.Create(Self);
|
||||
|
||||
|
|
@ -635,6 +640,9 @@ begin
|
|||
AddItem(MProject, 'Добавить дорожку', @MenuAddTrack);
|
||||
AddItem(MProject, 'Удалить последнюю дорожку', @MenuRemoveTrack);
|
||||
|
||||
MHelp := AddTop('Справка');
|
||||
AddItem(MHelp, 'О программе...', @MenuAbout);
|
||||
|
||||
{ Дважды, и оба раза нужны.
|
||||
|
||||
До присваивания — чтобы обработчики отрисовки стояли к первому показу.
|
||||
|
|
@ -656,6 +664,28 @@ end;
|
|||
Место справа в нижней полосе отводится сразу и насовсем, а надпись с
|
||||
полоской показываются только когда работа есть. Так строка состояния и
|
||||
показатель не наезжают друг на друга. }
|
||||
{ Значок окна. Вшит в программу, потому что рядом с ней может ничего не
|
||||
лежать. Значок самого файла программы под Windows задаётся не здесь, а
|
||||
ресурсом при сборке — это отдельная история. }
|
||||
procedure TMainForm.ApplyWindowIcon;
|
||||
var
|
||||
Stream: TMemoryStream;
|
||||
begin
|
||||
Stream := TMemoryStream.Create;
|
||||
try
|
||||
Stream.WriteBuffer(IconAppData[0], Length(IconAppData));
|
||||
Stream.Position := 0;
|
||||
try
|
||||
Icon.LoadFromStream(Stream);
|
||||
Application.Icon.Assign(Icon);
|
||||
except
|
||||
{ Со значком не вышло — работать это не мешает. }
|
||||
end;
|
||||
finally
|
||||
Stream.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.BuildJobIndicator;
|
||||
const
|
||||
JobWidth = 330;
|
||||
|
|
@ -724,6 +754,11 @@ begin
|
|||
ApplyLogVisible(not memoLog.Visible);
|
||||
end;
|
||||
|
||||
procedure TMainForm.MenuAbout(Sender: TObject);
|
||||
begin
|
||||
ShowAboutForm;
|
||||
end;
|
||||
|
||||
procedure TMainForm.MenuToggleLog(Sender: TObject);
|
||||
begin
|
||||
ApplyLogVisible(not memoLog.Visible);
|
||||
|
|
|
|||
192
src/uTheme.pas
|
|
@ -31,7 +31,8 @@ interface
|
|||
|
||||
uses
|
||||
Classes, SysUtils, Types, Controls, Graphics, Forms, StdCtrls, ExtCtrls,
|
||||
ComCtrls, Grids, Menus, Dialogs, Math, LCLType, LCLIntf, LCLProc;
|
||||
ComCtrls, Grids, Menus, Dialogs, Math, IntfGraphics, FPimage,
|
||||
LCLType, LCLIntf, LCLProc, uIconData;
|
||||
|
||||
const
|
||||
{ Порядок байт в TColor — $00BBGGRR, а не привычный RGB. У серых цветов
|
||||
|
|
@ -55,10 +56,13 @@ const
|
|||
type
|
||||
{ Значок на кнопке.
|
||||
|
||||
Рисуется кодом, а не берётся из файла: программа не должна зависеть
|
||||
от того, лежит ли рядом с ней картинка. Рисунки повторяют icons/*.svg
|
||||
— там они и придуманы, оттуда их можно перегнать в png для чего
|
||||
угодно ещё. }
|
||||
Картинки вшиты в программу (uIconData): зависеть от того, лежит ли
|
||||
рядом с ней файл, она не должна. Исходники — в icons_online, оттуда
|
||||
же требование указать авторство, см. окно «О программе».
|
||||
|
||||
Цвет значку задаётся при отрисовке: берётся прозрачность точки, а
|
||||
цвет — тот, каким сейчас рисуется кнопка. Поэтому один значок годится
|
||||
и для тёмной кнопки, и для оранжевой, и для недоступной. }
|
||||
TThemedIcon = (
|
||||
tiNone,
|
||||
tiSnap, // прилипание: края притягиваются к общей линии
|
||||
|
|
@ -296,6 +300,8 @@ type
|
|||
|
||||
var
|
||||
Painter: TThemePainter;
|
||||
{ Перекрашенные значки: ключ «номер значка : цвет». }
|
||||
IconCache: TStringList;
|
||||
{$IFDEF WINDOWS}
|
||||
{ Кисть под полосу меню. Создаётся один раз: Windows держит на неё
|
||||
ссылку, пока меню живо, и удалять её раньше нельзя. }
|
||||
|
|
@ -383,96 +389,101 @@ begin
|
|||
Invalidate;
|
||||
end;
|
||||
|
||||
{ Значки рисуются по клетке 24 на 24 — той же, что в icons/*.svg, — и
|
||||
переносятся в заданный прямоугольник. Так рисунок один и тот же при
|
||||
любом размере кнопки, и правится он в одном месте. }
|
||||
{ Значок в нужном цвете.
|
||||
|
||||
Картинка чёрная с прозрачностью, поэтому перекрашивается прямо по
|
||||
точкам: прозрачность остаётся своя, цвет ставится наш. Результат
|
||||
запоминается — цветов ровно три (обычный, на оранжевом, недоступный), и
|
||||
пересчитывать их на каждую перерисовку незачем. }
|
||||
function ThemedIconImage(AIcon: TThemedIcon; AColor: TColor):
|
||||
TPortableNetworkGraphic;
|
||||
var
|
||||
Key: string;
|
||||
Idx, X, Y: Integer;
|
||||
Stream: TMemoryStream;
|
||||
Img: TLazIntfImage;
|
||||
Px: TFPColor;
|
||||
R, G, B: Byte;
|
||||
begin
|
||||
Result := nil;
|
||||
if AIcon = tiNone then
|
||||
Exit;
|
||||
|
||||
Key := IntToStr(Ord(AIcon)) + ':' + IntToStr(AColor);
|
||||
if IconCache = nil then
|
||||
begin
|
||||
IconCache := TStringList.Create;
|
||||
IconCache.Sorted := True;
|
||||
IconCache.OwnsObjects := True;
|
||||
end;
|
||||
Idx := IconCache.IndexOf(Key);
|
||||
if Idx >= 0 then
|
||||
Exit(TPortableNetworkGraphic(IconCache.Objects[Idx]));
|
||||
|
||||
Stream := TMemoryStream.Create;
|
||||
try
|
||||
case AIcon of
|
||||
tiSnap: Stream.WriteBuffer(IconSnapData[0], Length(IconSnapData));
|
||||
tiRipple: Stream.WriteBuffer(IconRippleData[0], Length(IconRippleData));
|
||||
tiLog: Stream.WriteBuffer(IconLogData[0], Length(IconLogData));
|
||||
else
|
||||
Exit;
|
||||
end;
|
||||
Stream.Position := 0;
|
||||
|
||||
Result := TPortableNetworkGraphic.Create;
|
||||
try
|
||||
Result.LoadFromStream(Stream);
|
||||
{ Порядок байт в TColor обратный привычному. }
|
||||
R := AColor and $FF;
|
||||
G := (AColor shr 8) and $FF;
|
||||
B := (AColor shr 16) and $FF;
|
||||
|
||||
Img := Result.CreateIntfImage;
|
||||
try
|
||||
for Y := 0 to Img.Height - 1 do
|
||||
for X := 0 to Img.Width - 1 do
|
||||
begin
|
||||
Px := Img.Colors[X, Y];
|
||||
{ Прозрачное трогать незачем, а видимое красим целиком. }
|
||||
if Px.Alpha = 0 then
|
||||
Continue;
|
||||
Px.Red := R * 257;
|
||||
Px.Green := G * 257;
|
||||
Px.Blue := B * 257;
|
||||
Img.Colors[X, Y] := Px;
|
||||
end;
|
||||
Result.LoadFromIntfImage(Img);
|
||||
finally
|
||||
Img.Free;
|
||||
end;
|
||||
except
|
||||
FreeAndNil(Result);
|
||||
end;
|
||||
finally
|
||||
Stream.Free;
|
||||
end;
|
||||
|
||||
{ Неудачу тоже запоминаем: иначе разбирать картинку заново пришлось бы
|
||||
на каждой перерисовке. }
|
||||
IconCache.AddObject(Key, Result);
|
||||
end;
|
||||
|
||||
{ Значок рисуется без растягивания: картинка вшита ровно того размера, под
|
||||
который сделана кнопка. Если кнопка оказалась крупнее — значок остаётся
|
||||
своего размера и стоит по центру, а не расплывается. }
|
||||
procedure TThemedButton.DrawIcon(const ARect: TRect; AColor: TColor);
|
||||
var
|
||||
Side, X0, Y0: Integer;
|
||||
|
||||
function PX(AValue: Integer): Integer;
|
||||
begin
|
||||
Result := X0 + Round(AValue * Side / 24);
|
||||
end;
|
||||
|
||||
function PY(AValue: Integer): Integer;
|
||||
begin
|
||||
Result := Y0 + Round(AValue * Side / 24);
|
||||
end;
|
||||
|
||||
procedure Line(X1, Y1, X2, Y2: Integer);
|
||||
begin
|
||||
Canvas.Line(PX(X1), PY(Y1), PX(X2), PY(Y2));
|
||||
end;
|
||||
|
||||
procedure Box(X1, Y1, X2, Y2: Integer; AFilled: Boolean);
|
||||
begin
|
||||
if AFilled then
|
||||
Canvas.Brush.Style := bsSolid
|
||||
else
|
||||
Canvas.Brush.Style := bsClear;
|
||||
Canvas.Rectangle(PX(X1), PY(Y1), PX(X2), PY(Y2));
|
||||
end;
|
||||
|
||||
{ Треугольник остриём влево или вправо. Не Arrow: так называется
|
||||
свойство самой кнопки. }
|
||||
procedure Tri(ATipX, ABaseX, ACenterY, AHalf: Integer);
|
||||
begin
|
||||
Canvas.Brush.Style := bsSolid;
|
||||
Canvas.Polygon([Types.Point(PX(ATipX), PY(ACenterY)),
|
||||
Types.Point(PX(ABaseX), PY(ACenterY - AHalf)),
|
||||
Types.Point(PX(ABaseX), PY(ACenterY + AHalf))]);
|
||||
end;
|
||||
|
||||
Img: TPortableNetworkGraphic;
|
||||
X, Y: Integer;
|
||||
begin
|
||||
if FIcon = tiNone then
|
||||
Img := ThemedIconImage(FIcon, AColor);
|
||||
if (Img = nil) or (Img.Width = 0) then
|
||||
Exit;
|
||||
|
||||
Side := Min(ARect.Right - ARect.Left, ARect.Bottom - ARect.Top) - 6;
|
||||
if Side < 8 then
|
||||
Exit;
|
||||
X0 := (ARect.Left + ARect.Right - Side) div 2;
|
||||
Y0 := (ARect.Top + ARect.Bottom - Side) div 2;
|
||||
|
||||
Canvas.Pen.Color := AColor;
|
||||
Canvas.Pen.Width := Max(1, Side div 12);
|
||||
Canvas.Brush.Color := AColor;
|
||||
|
||||
case FIcon of
|
||||
tiSnap:
|
||||
begin
|
||||
{ Подкова магнита: дуга сверху, две ноги вниз, полюса закрашены.
|
||||
Без закрашенных полюсов подкова читается как перевёрнутая
|
||||
буква U и смысла не передаёт. }
|
||||
Canvas.Pen.Width := Max(2, Side div 6);
|
||||
Canvas.Brush.Style := bsClear;
|
||||
{ Дуга по верхней половине окружности с центром в (12,13). }
|
||||
Canvas.Arc(PX(5), PY(6), PX(19), PY(20), 0, 180 * 16);
|
||||
Line(5, 13, 5, 19);
|
||||
Line(19, 13, 19, 19);
|
||||
Canvas.Pen.Width := 1;
|
||||
Box(3, 18, 8, 23, True);
|
||||
Box(16, 18, 21, 23, True);
|
||||
end;
|
||||
tiRipple:
|
||||
begin
|
||||
{ Два куска и дыра между ними; стрелка показывает, что правый
|
||||
переедет влево. }
|
||||
Box(1, 7, 8, 17, True);
|
||||
Box(16, 7, 23, 17, True);
|
||||
Tri(10, 15, 12, 4);
|
||||
end;
|
||||
tiLog:
|
||||
begin
|
||||
Box(2, 3, 22, 21, False);
|
||||
Line(6, 8, 18, 8);
|
||||
Line(6, 12, 18, 12);
|
||||
Line(6, 16, 13, 16);
|
||||
end;
|
||||
end;
|
||||
|
||||
Canvas.Pen.Width := 1;
|
||||
Canvas.Brush.Style := bsClear;
|
||||
X := (ARect.Left + ARect.Right - Img.Width) div 2;
|
||||
Y := (ARect.Top + ARect.Bottom - Img.Height) div 2;
|
||||
Canvas.Draw(X, Y, Img);
|
||||
end;
|
||||
|
||||
procedure TThemedButton.Paint;
|
||||
|
|
@ -1286,5 +1297,6 @@ initialization
|
|||
|
||||
finalization
|
||||
Painter.Free;
|
||||
IconCache.Free;
|
||||
|
||||
end.
|
||||
|
|
|
|||
135
tools/make_icons.py
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Готовит модуль с данными значков из файлов в icons_online.
|
||||
|
||||
Зачем модулем, а не файлами рядом с программой: программа не должна
|
||||
зависеть от того, лежит ли что-то в её каталоге. Значки маленькие, все
|
||||
вместе занимают единицы килобайт.
|
||||
|
||||
Размер выбран под кнопку: у неё двадцать восемь точек стороны, значку
|
||||
достаётся клетка двадцать четыре на двадцать четыре. Уменьшение делает
|
||||
convert с обычным сглаживанием, пропорции при этом сохраняются — все
|
||||
исходники квадратные, растягивать нечего.
|
||||
|
||||
Запуск: python3 tools/make_icons.py
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
SRC = ROOT / 'icons_online'
|
||||
OUT = ROOT / 'src' / 'uIconData.pas'
|
||||
|
||||
# Имя в программе -> файл исходника и сторона в точках.
|
||||
# Для «схлопывания» берётся вариант на шестьдесят четыре точки: чем крупнее
|
||||
# исходник, тем чище получается уменьшение.
|
||||
ICONS = [
|
||||
('Snap', 'icons8-магнит-30.png', 24),
|
||||
('Ripple', 'icons8-merge-vertical-64.png', 24),
|
||||
('Log', 'icons8-property-30.png', 24),
|
||||
]
|
||||
|
||||
# Значок самой программы: отдельно, потому что окну нужен формат ico —
|
||||
# только его умеет читать TIcon в LCL.
|
||||
APP_ICON = ('icons8-показ-видеокадров-30.png', 32)
|
||||
|
||||
|
||||
def make_ico(path: Path, side: int) -> bytes:
|
||||
out = subprocess.run(
|
||||
['convert', str(path), '-background', 'none', '-alpha', 'on',
|
||||
'-resize', '%dx%d' % (side, side), 'ico:-'],
|
||||
check=True, capture_output=True)
|
||||
return out.stdout
|
||||
|
||||
|
||||
def scale(path: Path, side: int) -> bytes:
|
||||
out = subprocess.run(
|
||||
['convert', str(path), '-background', 'none', '-alpha', 'on',
|
||||
'-resize', '%dx%d' % (side, side), 'png:-'],
|
||||
check=True, capture_output=True)
|
||||
return out.stdout
|
||||
|
||||
|
||||
def pascal_bytes(data: bytes, indent: str = ' ') -> str:
|
||||
parts = []
|
||||
for i in range(0, len(data), 16):
|
||||
chunk = ', '.join('$%02X' % b for b in data[i:i + 16])
|
||||
parts.append(indent + chunk)
|
||||
return ',\n'.join(parts)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if not SRC.is_dir():
|
||||
print('нет каталога с исходниками:', SRC, file=sys.stderr)
|
||||
return 1
|
||||
|
||||
blocks = []
|
||||
names = []
|
||||
for name, filename, side in ICONS:
|
||||
path = SRC / filename
|
||||
if not path.is_file():
|
||||
print('нет файла:', path, file=sys.stderr)
|
||||
return 1
|
||||
data = scale(path, side)
|
||||
names.append((name, len(data)))
|
||||
blocks.append(
|
||||
' { %s, %d на %d точек }\n'
|
||||
' Icon%sData: array[0..%d] of Byte = (\n%s\n );'
|
||||
% (filename, side, side, name, len(data) - 1, pascal_bytes(data)))
|
||||
|
||||
app_src, app_side = APP_ICON
|
||||
app_path = SRC / app_src
|
||||
if not app_path.is_file():
|
||||
print('нет файла:', app_path, file=sys.stderr)
|
||||
return 1
|
||||
app_data = make_ico(app_path, app_side)
|
||||
names.append(('App (ico)', len(app_data)))
|
||||
blocks.append(
|
||||
' { %s, значок окна, %d на %d точек, формат ico }\n'
|
||||
' IconAppData: array[0..%d] of Byte = (\n%s\n );'
|
||||
% (app_src, app_side, app_side, len(app_data) - 1,
|
||||
pascal_bytes(app_data)))
|
||||
|
||||
text = '''{
|
||||
uIconData — значки, вшитые в программу.
|
||||
|
||||
Собран из файлов в icons_online командой:
|
||||
|
||||
python3 tools/make_icons.py
|
||||
|
||||
Правится не он, а исходные картинки: этот файл переписывается целиком.
|
||||
|
||||
Значки взяты у Icons8 и требуют указания авторства — оно есть в окне
|
||||
«О программе», вкладка «Библиотеки и авторство». Ссылки на каждый значок
|
||||
лежат в icons_online/attribution.txt.
|
||||
|
||||
Картинки чёрные на прозрачном фоне. Цвет им задаётся при отрисовке:
|
||||
берётся прозрачность точки, а цвет — тот, каким сейчас рисуется кнопка.
|
||||
Поэтому один и тот же значок годится и для тёмной кнопки, и для
|
||||
оранжевой.
|
||||
}
|
||||
unit uIconData;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
%s
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
''' % ('\n\n'.join(blocks))
|
||||
|
||||
OUT.write_text(text, encoding='utf-8')
|
||||
print('записан', OUT)
|
||||
for name, size in names:
|
||||
print(' %-8s %d байт' % (name, size))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||