This commit is contained in:
Valeria Fadeeva 2026-08-06 22:15:03 +05:00
parent d5b207150e
commit 36969310ea
15 changed files with 666 additions and 1041 deletions

View File

@ -629,8 +629,9 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found. the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.> melawy-plymouth-theme (melawy): Plymouth boot splash
Copyright (C) <year> <name of author> theme for Melawy OS.
Copyright (C) 2026 Valeria Fadeeva <valeria.fadeeva.me+melawy@gmail.com>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published it under the terms of the GNU Affero General Public License as published

View File

@ -1,5 +1,14 @@
#!/bin/bash #!/bin/bash
./install.sh set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR/.."
echo "=== Installing theme ==="
bash install.sh
echo ""
echo "=== Starting Plymouth daemon (debug mode) ==="
echo "Press Ctrl+C to stop"
sudo plymouthd --debug --no-daemon --tty=/dev/tty7 sudo plymouthd --debug --no-daemon --tty=/dev/tty7

View File

@ -1,43 +1,62 @@
#!/bin/bash #!/bin/bash
set -e
echo "=== Plymouth Theme Test Script ==="
# --- Запуск ---
echo "[1] Showing splash..."
sudo plymouth --show-splash sudo plymouth --show-splash
echo "[2] Setting boot mode..."
sudo plymouth change-mode --boot-up sudo plymouth change-mode --boot-up
echo "[3] Setting normal status..."
sudo plymouth update --status="normal" sudo plymouth update --status="normal"
# --- Тест паузы прогресса ---
echo "[4] Testing progress pause/resume..."
sudo plymouth pause-progress sudo plymouth pause-progress
sudo plymouth message --text="pausing boot - press 'c' or space bar to continue" sudo plymouth message --text="pausing boot - press 'c' or space bar to continue"
sleep 2 sleep 2
# sudo plymouth watch-keystroke --keys="cC " --command="tee /tmp/c_key_pressed"
sudo plymouth message --text="resuming boot" sudo plymouth message --text="resuming boot"
sudo plymouth unpause-progress sudo plymouth unpause-progress
#sudo plymouth ask-question --prompt "what is your name? " | /usr/bin/tee # --- Тест запроса пароля ---
sudo plymouth ask-for-password --prompt "specify password: /dev/sda8: LABEL=\"Data\" UUID=\"2fd2a700-319b-41f2-853f-c57667d4081d\" UUID_SUB=\"62109da7-2b4b-4c2d-b590-1c0436c7c3a4\" PARTUUID=\"c05c942b-bd7e-487a-87a0-592df3334ff5\"" | /usr/bin/tee echo "[5] Testing password prompt..."
sudo plymouth ask-for-password \
--prompt "specify password: /dev/sda8: LABEL=\"Data\" UUID=\"2fd2a700-319b-41f2-853f-c57667d4081d\" UUID_SUB=\"62109da7-2b4b-4c2d-b590-1c0436c7c3a4\" PARTUUID=\"c05c942b-bd7e-487a-87a0-592df3334ff5\"" \
| /usr/bin/tee || true
#sudo plymouth message --text="Hello" sleep 1
sudo plymouth --update=fsck:sda1:0 sudo plymouth ask-for-password \
sudo plymouth --update=fsck:sda1:1 --prompt "specify password: /dev/sda8: LABEL=\"Data\" UUID=\"c57667d4081d-319b-41f2-853f-2fd2a700\" UUID_SUB=\"1c0436c7c3a4-2b4b-4c2d-b590-62109da7\" PARTUUID=\"592df3334ff5-bd7e-487a-87a0-c05c942b\"" \
sudo plymouth --update=fsck:sda1:2 | /usr/bin/tee || true
sudo plymouth --update=fsck:sda1:3
sudo plymouth --update=fsck:sda1:4
sudo plymouth --update=fsck:sda1:5
sudo plymouth --update=fsck:sda1:6
sudo plymouth --update=fsck:sda1:7
sudo plymouth --update=fsck:sda1:8
sudo plymouth --update=fsck:sda1:9
sudo plymouth --update=fsck:sda1:10
sudo plymouth --update=fsck:sda1:11
sudo plymouth --update=fsck:sda1:12
sudo plymouth --update=fsck:sda1:27
sudo plymouth --update=fsck:sda1:54
sudo plymouth --update=fsck:sda1:100
# Возвращаемся к нормальному режиму после пароля
sudo plymouth update --status="normal"
# --- Тест FSCK прогресса ---
echo "[6] Testing fsck progress (0→100%)..."
for pct in 0 1 2 3 4 5 6 7 8 9 10 11 12 27 54 100; do
sudo plymouth --update="fsck:sda1:$pct"
done
# --- Тест скроллящегося лога ---
END=50 END=50
echo "[7] Testing scroll log ($END lines)..."
for i in $(seq 1 $END); do for i in $(seq 1 $END); do
sudo plymouth --update="$i длинная_строка_предлинная_строка_прямоот_такая" sudo plymouth --update="$i длинная_строка_предлинная_строка_прямоот_такая"
sudo plymouth --update="$i long_str_long_strlong_str_long_strlong_str_long_str" sudo plymouth --update="$i long_str_long_strlong_str_long_strlong_str_long_str"
done done
# --- Ожидание и завершение ---
echo "[8] Waiting 5 seconds before quit..."
sleep 5 sleep 5
echo "[9] Quitting Plymouth..."
sudo plymouth --quit sudo plymouth --quit
echo ""
echo "=== Test complete ==="

View File

@ -11,9 +11,9 @@ fi
./make.sh ./make.sh
sudo rm -rf /usr/share/plymouth/themes/$THEME_NAME sudo rm -vrf /usr/share/plymouth/themes/$THEME_NAME
sudo mkdir -p /usr/share/plymouth/themes/$THEME_NAME sudo mkdir -p /usr/share/plymouth/themes/$THEME_NAME
sudo cp -r ../$THEME_NAME /usr/share/plymouth/themes/ sudo cp -vr ../$THEME_NAME /usr/share/plymouth/themes/
ls -plash /usr/share/plymouth/themes/$THEME_NAME ls -plash /usr/share/plymouth/themes/$THEME_NAME

View File

@ -2,18 +2,25 @@
THEME_NAME="melawy" THEME_NAME="melawy"
if [[ -n "$THEME_NAME" ]]; then if [[ -z "$THEME_NAME" ]]; then
echo "Non empty"
else
echo "Theme name is empty. Exit" echo "Theme name is empty. Exit"
exit exit 1
fi fi
cp -f script.js ../$THEME_NAME/script.script SRC="../$THEME_NAME/script.script"
sed -i 's/function/fun/g' ../$THEME_NAME/script.script DST="$SRC"
if [[ "$?" == 0 ]]; then if [[ ! -f "$SRC" ]]; then
echo "Make successed" echo "Theme script $SRC not found. Exit"
exit 1
fi
# Проверяем наличие script.script в теме (без конвертации из JS)
cp -f "$SRC" "$DST"
if [[ $? -eq 0 ]]; then
echo "Make succeeded: $DST updated from $SRC"
else else
echo "Make failed?" echo "Make failed!"
exit 1
fi fi

View File

@ -1,709 +0,0 @@
/*
Theme Name: Melawy
Version: 1.0
Description: My theme
Author: Valeria Fadeeva - https://github.com/Valeria-Fadeeva
Date: 2023.04.04
License: GNU AFFERO GENERAL PUBLIC LICENSE, see <http://www.gnu.org/licenses/>
*/
Window.GetMaxWidth = function() {
i = 0;
width = 0;
while (Window.GetWidth(i)){
width = Math.Max(width, Window.GetWidth(i));
i++;
}
return width;
};
Window.GetMaxHeight = function() {
i = 0;
height = 0;
while (Window.GetHeight(i)){
height = Math.Max(height, Window.GetHeight(i));
i++;
}
return height;
};
Percent = function(perc, pixels) {
result = Math.Int(Math.Abs(Math.Int(pixels)) / 100 * Math.Abs(Math.Int(perc)));
return result;
};
Limit = function(width, height, perc) {
local.this;
this.width = width;
this.height = height;
this.perc = perc;
this.GetWidth = function() {
width = Percent(this.perc, this.width);
return width;
};
this.GetHeight = function() {
height = Percent(this.perc, this.height);
return height;
};
return this;
};
ScaleImage = function(image1, image2) {
img1.width = image1.GetWidth();
img1.height = image1.GetHeight();
img1.ratio = img1.width / img1.height;
img2.width = image2.GetWidth();
img2.height = image2.GetHeight();
img2.ratio = img2.width / img2.height;
if (img1.ratio == 1 || (img1.width < 200 && img1.height < 200)) {
img1.scaled = image1.Scale(img2.width, img2.height);
return img1.scaled;
}
if (img1.width == img2.width && img1.height == img2.height) {
return image1;
}
if (img2.ratio < img1.ratio) {
factor = img2.height / img1.height;
} else {
factor = img2.width / img1.width;
}
img1.scaled = image1.Scale(img1.width * factor, img1.height * factor);
return img1.scaled;
};
FitIntoDimensions = function(image1, image2) {
img1.width = image1.GetWidth();
img1.height = image1.GetHeight();
img2.width = image2.GetWidth();
img2.height = image2.GetHeight();
ma = Math.Max(img1.width, img2.height);
mi = Math.Min(img1.height, img2.height);
factor = ma / mi;
img1.fit = image1.Scale(Math.Int(img1.width / factor), Math.Int(img1.height / factor));
};
SetSpriteImage = function(asset, x, y, z) {
local.sprite = Sprite();
sprite.image = Image(asset);
sprite.width = sprite.image.GetWidth();
sprite.height = sprite.image.GetHeight();
sprite.SetImage(sprite.image);
sprite.SetPosition(x, y, z);
return sprite;
};
Blur = function(background_src, foreground_src, x, y, z, width, height, scale_width, scale_height) {
index = 0;
local.image[index];
image[index].image = Image(background_src);
image[index].image = ScaleImage(image[index].image, Limit(scale_width, scale_height, 100));
image[index].image = image[index].image.Crop(x, y, width, height);
image[index].image = ScaleImage(image[index].image, Limit(Percent(120, width), Percent(120, height), 100));
image[index].image = image[index].image.Crop(x, y, width, height);
image[index].sprite0 = Sprite(image[index].image);
image[index].sprite1 = Sprite(image[index].image);
image[index].sprite2 = Sprite(image[index].image);
image[index].sprite3 = Sprite(image[index].image);
image[index].sprite4 = Sprite(image[index].image);
image[index].sprite0.SetOpacity(0.25);
image[index].sprite1.SetOpacity(0.25);
image[index].sprite2.SetOpacity(0.25);
image[index].sprite3.SetOpacity(0.25);
image[index].sprite4.SetOpacity(0.25);
image[index].sprite0.SetPosition(x, y, z);
image[index].sprite1.SetPosition(x++, y, z++);
image[index].sprite2.SetPosition(x, y++, z++);
image[index].sprite3.SetPosition(x--, y, z++);
image[index].sprite5.SetPosition(x, y--, z++);
index = 1;
image[index].image = Image(foreground_src);
image[index].image = image[index].image.Scale(width, height);
image[index].sprite = Sprite(image[index].image);
image[index].sprite.SetOpacity(0.75);
image[index].sprite.SetPosition(x, y, z++);
return local.image;
};
// TEXT
common_font = "Noto Sans Mono Regular 10";
progress_font = "Noto Sans Mono Regular 12";
link_font = "Noto Sans Italic 16";
common_symbol.image = Image.Text("M", 0.5, 0.5, 0.5, 1, common_font);
common_symbol.height = common_symbol.image.GetHeight(); // высота символа
common_symbol.width = common_symbol.image.GetWidth(); // ширина символа
progress_symbol.image = Image.Text("M", 0.5, 0.5, 0.5, 1, progress_font);
progress_symbol.height = progress_symbol.image.GetHeight(); // высота символа
progress_symbol.width = progress_symbol.image.GetWidth(); // ширина символа
link_symbol.image = Image.Text("M", 0.5, 0.5, 0.5, 1, link_font);
link_symbol.height = link_symbol.image.GetHeight(); // высота символа
link_symbol.width = link_symbol.image.GetWidth(); // ширина символа
starting_text = "Starting up...";
bye_text = "System is shutting down";
progress_t= 0;
// x0 = Window.GetX();
// y0 = Window.GetY();
// z0 = Window.GetZ();
x0 = 0;
y0 = 0;
z0 = 0;
Window.SetBackgroundTopColor(0, 0, 0);
Window.SetBackgroundBottomColor(0, 0, 0);
screen.width = Window.GetMaxWidth();
screen.height = Window.GetMaxHeight();
// BACKGROUND
background.image = Image("BACKGROUND.png");
background.image = ScaleImage(background.image, Limit(screen.width, screen.height, 100));
background.width = background.image.GetWidth();
background.height = background.image.GetHeight();
background.x = x0 + screen.width / 2 - background.width / 2;
background.y = y0 + screen.height / 2 - background.height / 2;
//background.x = x0;
//background.y = y0;
background.sprite = SpriteNew();
background.sprite.SetImage(background.image);
background.sprite.SetOpacity(1);
background.sprite.SetPosition(background.x, background.y, 0);
// SIDE BACKGROUND
side_panel.background_src = "BACKGROUND.png";
side_panel.foreground_src = "SIDE_BACKGROUND2.png";
side_panel.x = x0;
side_panel.y = y0;
side_panel.z = 1;
side_panel.width = Percent(33.33, screen.width);
side_panel.height = Percent(100, screen.height);
blur = Blur(side_panel.background_src, side_panel.foreground_src, side_panel.x, side_panel.y, side_panel.z, side_panel.width, side_panel.height, screen.width, screen.height);
// MESSAGES BOX
messages_box.image = Image("MESSAGES_BOX.png");
messages_box.image = messages_box.image.Scale(Percent(80, side_panel.width), Percent(40, side_panel.height));
messages_box.width = messages_box.image.GetWidth();
messages_box.height = messages_box.image.GetHeight();
messages_box.x = Percent(50, side_panel.width) - messages_box.width / 2;
messages_box.y = Percent(45, side_panel.height) - messages_box.height;
messages_box.sprite = Sprite(messages_box.image);
messages_box.sprite.SetOpacity(1);
messages_box.sprite.SetPosition(messages_box.x, messages_box.y, 12);
// Sise Logo
side_logo.image = Image("Melawy_Linux_640x320.png");
side_logo.image = ScaleImage(side_logo.image, Limit(screen.width, screen.height, 20));
side_logo.width = side_logo.image.GetWidth();
side_logo.height = side_logo.image.GetHeight();
side_logo.x = (side_panel.width - side_logo.width) / 2;
side_logo.y = side_panel.height - side_panel.height * 0.25;
side_logo.sprite = Sprite(side_logo.image);
side_logo.sprite.SetOpacity(1);
side_logo.sprite.SetPosition(side_logo.x, side_logo.y, 12);
// **************************************** //
project_link.image = Image.Text("https://Melawy.ru", 0.5, 0.5, 0.5, 1, link_font);
project_link.width = project_link.image.GetWidth();
project_link.height = project_link.image.GetHeight();
project_link.sprite = Sprite(project_link.image);
project_link.x = (side_panel.width - project_link.width) / 2;
project_link.y = side_logo.y + side_logo.height;
project_link.sprite.SetOpacity(1);
project_link.sprite.SetPosition(project_link.x, project_link.y, 12);
// **************************************** //
// LOGO
logo.image = Image("MAIN_LOGO.png");
logo.image = FitIntoDimensions(logo.image, Limit(screen.width, screen.height, 35));
logo.sprite = Sprite(logo.image);
logo.x = screen.width / 2 - logo.image.GetWidth() / 2; // позиция логотипа X
logo.y = Percent(10, screen.height); // позиция логотипа Y
logo.sprite.SetOpacity(1);
logo.sprite.SetPosition(logo.x, logo.y, 12);
// PROGRESS FORM
progress_form.image = Image("PROGRESS_FORM.png");
progress_form.image = progress_form.image.Scale(Percent(80, side_panel.width), Percent(10, side_panel.height));
progress_form.width = progress_form.image.GetWidth();
progress_form.height = progress_form.image.GetHeight();
progress_form.x = Percent(50, side_panel.width) - progress_form.width / 2;
progress_form.y = Percent(75, side_panel.height) - progress_form.height;
progress_form.sprite = Sprite(progress_form.image);
progress_form.sprite.SetOpacity(1);
progress_form.sprite.SetPosition(progress_form.x, progress_form.y, 12);
// SPINNER
spinner.image = Image("SPINNER.png");
spinner.image = spinner.image.Scale(Percent(1, screen.width), Percent(1, screen.width));
spinner.width = spinner.image.GetWidth();
spinner.height = spinner.image.GetHeight();
spinner.x = progress_form.x + progress_form.width - Percent(10, progress_form.width);
spinner.y = progress_form.y + Percent(10, progress_form.height);
spinner.sprite = Sprite(spinner.image);
spinner.sprite.SetPosition(spinner.x, spinner.y, 13); // позиция за или перед
// PROGRESS TEXT
progress_text.image = Image.Text(progress_t + "%", 0.5, 0.5, 0.5, 1, progress_font);
progress_text.width = progress_text.image.GetWidth();
progress_text.height = progress_text.image.GetHeight();
progress_text.x = progress_form.x + Percent(5, progress_form.width); // позиция % по X
progress_text.y = progress_form.y + Percent(10, progress_form.height); // позиция % по Y
progress_text.sprite = SpriteNew();
progress_text.sprite.SetPosition(progress_text.x, progress_text.y, 13);
// PROGRESS BOX
progress_box.image = Image("PROGRESS_BOX.png");
progress_box.image = progress_box.image.Scale(Percent(90, progress_form.width), Percent(15, progress_form.height));
progress_box.width = progress_box.image.GetWidth();
progress_box.height = progress_box.image.GetHeight();
progress_box.x = progress_form.x + (progress_form.width - progress_box.width) / 2;
progress_box.y = progress_form.y + (progress_form.height - progress_box.height) / 2;
progress_box.sprite = Sprite(progress_box.image);
progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 13);
// PROGRESS BAR
progress_bar.original_image = Image("PROGRESS_BAR.png");
progress_bar.original_image = progress_bar.original_image.Scale(Percent(90, progress_form.width), Percent(15, progress_form.height));
progress_bar.width = progress_bar.original_image.GetWidth();
progress_bar.height = progress_bar.original_image.GetHeight();
progress_bar.x = progress_form.x + (progress_form.width - progress_bar.original_image.GetWidth()) / 2;
progress_bar.y = progress_form.y + (progress_form.height - progress_bar.original_image.GetHeight()) / 2;
progress_bar.sprite = Sprite();
progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 14);
// PROGRESS FADE
progress_fade.image = Image("PROGRESS_FADE.png");
progress_fade.image = progress_fade.image.Scale(Percent(10, progress_form.width), Percent(15, progress_form.height));
progress_fade.width = progress_fade.image.GetWidth();
progress_fade.height = progress_fade.image.GetHeight();
progress_fade.sprite = Sprite(progress_fade.image);
fade_dir = 0; // 0 = right, 1 = left
counter = 0;
max_counter = progress_box.width - progress_fade.width;
function progress_callback(duration, progress) {
if (progress_bar.image.GetWidth() != Math.Int(progress_bar.original_image.GetWidth() * progress)) {
progress_bar.image = progress_bar.original_image.Scale(progress_bar.original_image.GetWidth(progress_bar.original_image) * progress, progress_bar.original_image.GetHeight());
progress_bar.sprite.SetImage(progress_bar.image);
f = Math.Int(progress_bar.image.GetWidth() /progress_bar.original_image.GetWidth() * 100);
progress_t.image = Image.Text(f + "%", 0.5, 0.5, 0.5, 1, progress_font);
progress_text.sprite.SetImage(progress_t.image);
}
}
Plymouth.SetBootProgressFunction(progress_callback);
// DIALOG
status = "normal";
//count = 0;
function dialog_setup() {
local.box_form;
local.lock;
local.entry;
local.hint;
local.bullet_i;
box_form.image = Image("BOX.png");
box_form.image = box_form.image.Scale(Percent(80, side_panel.width), Percent(18, side_panel.height));
box_form.width = box_form.image.GetWidth();
box_form.height = box_form.image.GetHeight();
box_form.x = progress_form.x;
box_form.y = progress_form.y - box_form.height - Percent(1, side_panel.height);
box_form.z = 10000;
box_form.sprite = Sprite(box_form.image);
box_form.sprite.SetOpacity(1);
box_form.sprite.SetPosition(box_form.x, box_form.y, box_form.z);
entry.image = Image("ENTRY.png");
entry.image = entry.image.Scale(Percent(90, box_form.width), Percent(20, box_form.height));
entry.width = entry.image.GetWidth();
entry.height = entry.image.GetHeight();
entry.x = box_form.x + box_form.width/2 - entry.width/2;
entry.y = box_form.y + (box_form.height/3 * 2) - entry.height/2;
entry.z = box_form.z + 1;
entry.sprite = Sprite(entry.image);
entry.sprite.SetPosition(entry.x, entry.y, entry.z);
lock.image = Image("LOCK.png");
lock.image = lock.image.Scale(Percent(95, entry.height), Percent(95, entry.height));
lock.width = lock.image.GetWidth();
lock.height = lock.image.GetHeight();
lock.x = entry.x + entry.width - lock.width - (entry.height - lock.height);
lock.y = entry.y + entry.height/2 - lock.height/2;
lock.z = box_form.z + 2;
lock.sprite = Sprite(lock.image);
lock.sprite.SetPosition(lock.x, lock.y, lock.z);
hint.sprite = SpriteNew();
hint.sprite.SetPosition(entry.x, box_form.y + Percent(5, box_form.height), box_form.z + 1);
bullet_i.image = Image("BULLET.png");
bullet_i.image = bullet_i.image.Scale(Percent(50, entry.height), Percent(50, entry.height));
bullet_i.width = bullet_i.image.GetWidth();
bullet_i.height = bullet_i.image.GetHeight();
global.dialog.box_form = box_form;
global.dialog.lock = lock;
global.dialog.entry = entry;
global.dialog.hint = hint;
global.dialog.bullet_i = bullet_i;
dialog_opacity(1);
}
function dialog_opacity(opacity) {
if (opacity == 0) {
dialog.box_form.sprite.SetOpacity(opacity);
dialog.lock.sprite.SetOpacity(opacity);
dialog.entry.sprite.SetOpacity(opacity);
}
else {
dialog.lock.sprite.SetOpacity(opacity);
dialog.entry.sprite.SetOpacity(opacity);
}
dialog.hint.sprite.SetOpacity(opacity);
for (index = 0; dialog.bullet[index]; index++) {
dialog.bullet[index].sprite.SetOpacity(opacity);
}
}
function display_normal_callback() {
global.status = "normal";
if (global.dialog)
dialog_opacity(0);
}
Plymouth.SetDisplayNormalFunction(display_normal_callback);
function display_password_callback(prompt_text, bullets) {
global.status = "password";
if (!global.dialog)
dialog_setup();
else
dialog_opacity(1);
padding_top_bottom = Percent(10, dialog.box_form.height); // отступы сверху и снизу
padding_left_right = Percent(5, dialog.box_form.width); // отступы слева и справа
LINE_WIDTH = 100;
for (index = LINE_WIDTH; index > 0; index--) {
if ((LINE_WIDTH * common_symbol.width) > (dialog.box_form.width - (padding_left_right * 2))) {
LINE_WIDTH = LINE_WIDTH - 1;
}
else {
break;
}
}
str_len = StringLength(prompt_text);
for (i = 1; LINE_WIDTH * i <= str_len; i++) {
line_count = i;
}
if (str_len > LINE_WIDTH) {
if (str_len % LINE_WIDTH > 0) {
line_count = line_count + 1;
}
}
i = 1;
start = 0;
end = LINE_WIDTH;
text = "";
for (i = 1; i <= line_count; i++) {
text += prompt_text.SubString(start, end);
text += "\n";
start = end;
if (LINE_WIDTH * i < str_len) {
end = end + LINE_WIDTH;
}
else {
end = str_len - 1;
}
}
prompt_text = text;
dialog.hint.image = Image.Text(prompt_text, 0.5, 0.5, 0.5, 1, common_font);
dialog.hint.sprite.SetImage(dialog.hint.image);
for (index = 0; dialog.bullet[index] || index < bullets; index++) {
if (!dialog.bullet[index]) {
dialog.bullet[index].sprite = Sprite(dialog.bullet_i.image);
dialog.bullet[index].x = dialog.entry.x + index * dialog.bullet_i.width / 0.9 - dialog.entry.height * -0.2; // отступ точки от точки и от поля(modified)
dialog.bullet[index].y = dialog.entry.y + (dialog.entry.height - dialog.bullet_i.height) / 2;
dialog.bullet[index].z = dialog.entry.z + 1;
dialog.bullet[index].sprite.SetPosition(dialog.bullet[index].x, dialog.bullet[index].y, dialog.bullet[index].z);
}
if (index < bullets)
dialog.bullet[index].sprite.SetOpacity(1);
else
dialog.bullet[index].sprite.SetOpacity(0);
}
}
Plymouth.SetDisplayPasswordFunction(display_password_callback);
time = 1;
function refreshHandler() {
if (global.status == "normal" && Plymouth.GetMode() == "boot") {
progress_fade.sprite.SetOpacity (0); // полностью прозрачный
progress_bar.sprite.SetOpacity (1);
text.image = Image.Text(starting_text, 0.5, 0.5, 0.5, 1, common_font);
text.sprite = Sprite(text.image);
text.x = progress_box.x;
text.y = progress_box.y - progress_text.image.GetHeight() * 2;
text.sprite.SetPosition(text.x, text.y, 13);
}
else {
progress_fade.sprite.SetOpacity (1);
progress_bar.sprite.SetOpacity (0);
text_end.image = Image.Text(bye_text, 0.5, 0.5, 0.5, 1, common_font);
text_end.sprite = Sprite(text_end.image);
text_end.x = progress_box.x;
text_end.y = progress_box.y - progress_text.image.GetHeight() * 2;
text_end.sprite.SetPosition(text_end.x, text_end.y, 13);
}
progress_fade.x = progress_bar.x;
progress_fade.y = progress_bar.y;
progress_fade.sprite.SetPosition(counter + progress_fade.x, progress_fade.y, 14);
if (fade_dir == 0) {
counter++;
if (counter >= max_counter) {
fade_dir = 1;
}
}
else {
counter--;
if (counter <= 0) {
fade_dir = 0;
}
}
/* if fsck is running or the password is prompted, hide the spinner */
if (fsck_running == 1 || passw_dialog_input_sprite.GetOpacity() == 1) {
spinner.sprite.SetOpacity(0);
}
else {
spinner.sprite.SetOpacity(1);
time++;
theta = time / (Math.Pi * 2);
spinner.sprite.SetImage(spinner.image.Rotate(theta));
}
if ((fsck_running == 1) && (fsck_done_fading == 0)) {
fsck_progress_meter_sprite.SetOpacity(fsck_fade_in_counter);
fsck_progress_fade_sprite.SetOpacity(fsck_fade_in_counter);
if (fsck_fade_in_counter < 1) {
fsck_fade_in_counter+= 0.025;
}
else {
fsck_done_fading = 1;
}
}
}
Plymouth.SetRefreshFunction(refreshHandler);
message_status.sprite = SpriteNew();
function message_callback(prompt_text) {
message_status.image = Image.Text(prompt_text, 0.5, 0.5, 0.5, 1, common_font);
message_status.sprite.SetImage(message_status.image);
message_status.height = message_status.image.GetHeight();
message_status.x = messages_box.x + Percent(5, messages_box.width);
message_status.y = messages_box.y + messages_box.height - Percent(7, messages_box.height);
message_status.sprite.SetOpacity(1);
message_status.sprite.SetPosition(message_status.x, message_status.y, 13);
}
Plymouth.SetMessageFunction(message_callback);
// высота messages_box = screen.height - 40% (1080 * 0,4 = 432)
// высота всех сообщений = NUM_SCROLL_LINES (20) * (LINE_HEIGHT) 17 = 340
// 10 процентов сверху от начала messages_box.x = 432 - 10% (432 * 0,1) = 432 - 43 = 389
// конечная точка, где допустимо показывать сообщения = 389 - 43 (10% от высоты messages_box.x) = 346
// если высота всех сообщений выше, чем высота (messages_box.height - 20%), то уменьшать количество строк, пока высота всех сообщений не быдет меньше (messages_box.height - 20%)
// высота символа = common_font = 10pt, предположим что 10px
// предположим, что ширина символа = 60% от высоты символа = 6px
// ширина side_panel = 25% от screen.width = 1080 * 0.25 = 270
// ширина messages_box = 80 % от side_panel = 270 * 0.8 = 216
// ширина всех сообщений = LINE_WIDTH * ширину символа = 40 * 6 = 240
// необходимо снижать количество LINE_WIDTH пока реальная ширина сообщения не будет меньше или равно ширине messages_box
padding_top_bottom = Percent(10, messages_box.height); // отступы сверху и снизу
padding_left_right = Percent(5, messages_box.width); // отступы слева и справа
message_sprite_.x = messages_box.x + (padding_left_right); // позиция % по X (слева направо)
message_sprite_.y = messages_box.y + (padding_top_bottom); // позиция % по Y (сверху вниз)
// LOG //
NUM_SCROLL_LINES=100; //количество строк лога
LINE_WIDTH=100; //ширина строк лога
LINE_HEIGHT = common_symbol.height * 1.5; // межстрочный интервал x1,5
for (index = NUM_SCROLL_LINES; index > 0; index--) {
if ((NUM_SCROLL_LINES * LINE_HEIGHT) > (messages_box.height - (padding_top_bottom * 2))) {
NUM_SCROLL_LINES=NUM_SCROLL_LINES-1;
}
else {
break;
}
}
for (index = LINE_WIDTH; index > 0; index--) {
if ((LINE_WIDTH * common_symbol.width) > (messages_box.width - (padding_left_right * 2))) {
LINE_WIDTH=LINE_WIDTH-1;
}
else {
break;
}
}
// Initialising text images and their positions
// 20 is the height(including line spacing) of each line
for (i=0; i < NUM_SCROLL_LINES; i++) {
lines[i]= Image.Text("", 0.5, 0.5, 0.5, 1, common_font); //цвет строк
message_sprite[i] = SpriteNew();
message_sprite[i].SetPosition(message_sprite_.x, message_sprite_.y + (i * LINE_HEIGHT), 13);
} //высота строк //отступ строк
function StringLength(string) {
index = 0;
str = String(string);
while(str.CharAt(index)) index++;
return index;
}
function scroll_message_callback(text) {
// Truncate the message if too long
if (StringLength(text) > LINE_WIDTH) {
text = text.SubString(0, LINE_WIDTH - 3);
text += "...";
}
// Shift message one up
for (i = 0; i < NUM_SCROLL_LINES - 1; i++) {
lines[i] = lines[i+1];
}
// Create the image for the latest message
lines[i] = Image.Text(text, 0.5, 0.5, 0.5, 1, common_font);
// Re-positioning the text images
for (i = 0; i < NUM_SCROLL_LINES; i++) {
message_sprite[i].SetImage(lines[i]);
}
}
Plymouth.SetUpdateStatusFunction(scroll_message_callback);
// QUIT
function quit_callback() {
progress_fade.sprite.SetOpacity (1);
progress_bar.sprite.SetOpacity (0);
if (Plymouth.GetMode() == "shutdown") {
logo.sprite.SetOpacity(0);
}
}
Plymouth.SetQuitFunction(quit_callback);

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="150mm"
viewBox="0 0 100 150"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="MESSAGGES_BOX.svg"
inkscape:export-filename="MESSAGES_BOX.png"
inkscape:export-xdpi="93"
inkscape:export-ydpi="93"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0419012"
inkscape:cx="-71.983793"
inkscape:cy="323.92707"
inkscape:window-width="1920"
inkscape:window-height="1006"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Слой 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="mix-blend-mode:normal;fill:#cccccc;fill-opacity:1;stroke:#a03d40;stroke-width:0.5;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect788"
width="100"
height="150"
x="0"
y="0"
ry="0"
inkscape:export-filename="MESSAGES_BOX.png"
inkscape:export-xdpi="25.4"
inkscape:export-ydpi="25.4" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="10mm"
viewBox="0 0 100 10"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="MESSAGGE_STATUS_BOX.svg"
inkscape:export-filename="MESSAGE_STATUS.png"
inkscape:export-xdpi="93"
inkscape:export-ydpi="93"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.9469416"
inkscape:cx="199.52889"
inkscape:cy="45.640538"
inkscape:window-width="1920"
inkscape:window-height="1006"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Слой 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="mix-blend-mode:normal;fill:#cccccc;fill-opacity:1;stroke:#a03d40;stroke-width:0.5;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect788"
width="100"
height="10"
x="0"
y="0"
ry="0"
inkscape:export-filename="MESSAGE_STATUS_BOX.png"
inkscape:export-xdpi="25.4"
inkscape:export-ydpi="25.4" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

56
dev/test_quick.sh Executable file
View File

@ -0,0 +1,56 @@
#!/bin/bash
#
# Быстрый режим тестирования Plymouth-темы БЕЗ пересборки initramfs
# Просто копирует файлы и запускает демон для интерактивного тестирования
#
# Использование:
# Окно 1: ./test_quick.sh (запуск демона)
# Окно 2: ./d1.sh (тестовые команды)
#
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$SCRIPT_DIR/.."
THEME_NAME="melawy"
THEME_PATH="/usr/share/plymouth/themes/$THEME_NAME"
echo "============================================"
echo " Быстрое тестирование Plymouth-темы"
echo " Тема: $THEME_NAME"
echo "============================================"
echo ""
# --- Проверка прав ---
if [[ "$UID" != 0 ]]; then
echo "[!] Требуется root, перезапуск через sudo..."
exec sudo "$0" "$@"
fi
# --- Копирование файлов ---
echo "[1] Копирование темы в $THEME_PATH ..."
mkdir -p "$THEME_PATH"
cp -vrf --remove-destination --no-dereference --preserve=links \
"$PROJECT_DIR/$THEME_NAME/." "$THEME_PATH/."
echo " ✓ Файлы скопированы"
# --- Установка темы по умолчанию (без -R = без пересборки initramfs!) ---
echo "[2] Установка темы по умолчанию (БЕЗ пересборки initramfs)..."
plymouth-set-default-theme "$THEME_NAME"
echo " ✓ Тема установлена"
echo ""
echo "============================================"
echo " Запуск Plymouth daemon (debug mode)"
echo " В ДРУГОМ ОКНЕ выполните:"
echo " cd $(dirname "$0")"
echo " bash d1.sh"
echo ""
echo " Нажмите Ctrl+C для остановки"
echo "============================================"
echo ""
sleep 2
# --- Запуск демона ---
exec sudo plymouthd --debug --no-daemon --tty=/dev/tty7

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
melawy/MAIN_LOGO_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because it is too large Load Diff