diff --git a/LICENSE b/LICENSE index 0ad25db..f45f21c 100644 --- a/LICENSE +++ b/LICENSE @@ -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 the "copyright" line and a pointer to where the full notice is found. - - Copyright (C) + melawy-plymouth-theme-lera-sugar (lera-sugar): Plymouth boot splash + theme for Melawy OS. + Copyright (C) 2026 Valeria Fadeeva 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 diff --git a/dev/d0.sh b/dev/d0.sh index 507c408..bce16c3 100755 --- a/dev/d0.sh +++ b/dev/d0.sh @@ -1,5 +1,14 @@ #!/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 diff --git a/dev/d1.sh b/dev/d1.sh index 87bf8cd..db19d3f 100755 --- a/dev/d1.sh +++ b/dev/d1.sh @@ -1,43 +1,62 @@ #!/bin/bash +set -e + +echo "=== Plymouth Theme Test Script ===" + +# --- Запуск --- +echo "[1] Showing splash..." sudo plymouth --show-splash + +echo "[2] Setting boot mode..." sudo plymouth change-mode --boot-up + +echo "[3] Setting normal status..." sudo plymouth update --status="normal" +# --- Тест паузы прогресса --- +echo "[4] Testing progress pause/resume..." sudo plymouth pause-progress sudo plymouth message --text="pausing boot - press 'c' or space bar to continue" sleep 2 -# sudo plymouth watch-keystroke --keys="cC " --command="tee /tmp/c_key_pressed" sudo plymouth message --text="resuming boot" 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 --update=fsck:sda1:1 -sudo plymouth --update=fsck:sda1:2 -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 ask-for-password \ + --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\"" \ + | /usr/bin/tee || true +# Возвращаемся к нормальному режиму после пароля +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 +echo "[7] Testing scroll log ($END lines)..." for i in $(seq 1 $END); do sudo plymouth --update="$i длинная_строка_предлинная_строка_прямо_вот_такая" sudo plymouth --update="$i long_str_long_strlong_str_long_strlong_str_long_str" done +# --- Ожидание и завершение --- +echo "[8] Waiting 5 seconds before quit..." sleep 5 + +echo "[9] Quitting Plymouth..." sudo plymouth --quit + +echo "" +echo "=== Test complete ===" diff --git a/dev/install.sh b/dev/install.sh index 7b41931..bf65b35 100755 --- a/dev/install.sh +++ b/dev/install.sh @@ -11,9 +11,9 @@ fi ./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 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 diff --git a/dev/make.sh b/dev/make.sh index afb15da..82d883e 100755 --- a/dev/make.sh +++ b/dev/make.sh @@ -2,18 +2,25 @@ THEME_NAME="melawy-lera-sugar" -if [[ -n "$THEME_NAME" ]]; then - echo "Non empty" -else +if [[ -z "$THEME_NAME" ]]; then echo "Theme name is empty. Exit" - exit + exit 1 fi -cp -f script.js ../$THEME_NAME/script.script -sed -i 's/function/fun/g' ../$THEME_NAME/script.script +SRC="../$THEME_NAME/script.script" +DST="$SRC" -if [[ "$?" == 0 ]]; then - echo "Make successed" +if [[ ! -f "$SRC" ]]; then + 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 - echo "Make failed?" + echo "Make failed!" + exit 1 fi diff --git a/dev/script.js b/dev/script.js deleted file mode 100644 index a7a1900..0000000 --- a/dev/script.js +++ /dev/null @@ -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 -*/ - -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); diff --git a/dev/test_quick.sh b/dev/test_quick.sh new file mode 100755 index 0000000..581ee42 --- /dev/null +++ b/dev/test_quick.sh @@ -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-lera-sugar" +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 diff --git a/melawy-lera-sugar/MAIN_LOGO.png b/melawy-lera-sugar/MAIN_LOGO.png index 3b63a5e..f080f10 100644 Binary files a/melawy-lera-sugar/MAIN_LOGO.png and b/melawy-lera-sugar/MAIN_LOGO.png differ diff --git a/melawy-lera-sugar/MAIN_LOGO_.png b/melawy-lera-sugar/MAIN_LOGO_.png new file mode 100644 index 0000000..3b63a5e Binary files /dev/null and b/melawy-lera-sugar/MAIN_LOGO_.png differ diff --git a/melawy-lera-sugar/Melawy_Linux_640x320.png b/melawy-lera-sugar/Melawy_Linux_640x320.png deleted file mode 100644 index 5fb656f..0000000 Binary files a/melawy-lera-sugar/Melawy_Linux_640x320.png and /dev/null differ diff --git a/melawy-lera-sugar/script.script b/melawy-lera-sugar/script.script index db37512..4f98925 100644 --- a/melawy-lera-sugar/script.script +++ b/melawy-lera-sugar/script.script @@ -1,16 +1,23 @@ /* -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 -*/ + Theme Name: melawy-plymouth-theme-neon-recline (neon-recline) + Version: 3.0 + Description: Plymouth boot splash theme for Melawy OS + Author: Valeria Fadeeva + https://github.com/Valeria-Fadeeva + https://github.com/Melawy + https://gitlab.com/melawy/ + Date: 2026.07.24 + License: GNU AFFERO GENERAL PUBLIC LICENSE, see + */ + +// ============================================================ +// УТИЛИТЫ +// ============================================================ Window.GetMaxWidth = fun() { i = 0; width = 0; - while (Window.GetWidth(i)){ + while (Window.GetWidth(i)) { width = Math.Max(width, Window.GetWidth(i)); i++; } @@ -20,7 +27,7 @@ Window.GetMaxWidth = fun() { Window.GetMaxHeight = fun() { i = 0; height = 0; - while (Window.GetHeight(i)){ + while (Window.GetHeight(i)) { height = Math.Max(height, Window.GetHeight(i)); i++; } @@ -28,8 +35,7 @@ Window.GetMaxHeight = fun() { }; Percent = fun(perc, pixels) { - result = Math.Int(Math.Abs(Math.Int(pixels)) / 100 * Math.Abs(Math.Int(perc))); - return result; + return Math.Int(Math.Abs(Math.Int(pixels)) / 100 * Math.Abs(Math.Int(perc))); }; Limit = fun(width, height, perc) { @@ -39,135 +45,143 @@ Limit = fun(width, height, perc) { this.perc = perc; this.GetWidth = fun() { - width = Percent(this.perc, this.width); - return width; + return Percent(this.perc, this.width); }; this.GetHeight = fun() { - height = Percent(this.perc, this.height); - return height; + return Percent(this.perc, this.height); }; return this; }; ScaleImage = fun(image1, image2) { - img1.width = image1.GetWidth(); - img1.height = image1.GetHeight(); - img1.ratio = img1.width / img1.height; + local.img1_w = image1.GetWidth(); + local.img1_h = image1.GetHeight(); + local.img1_ratio = img1_w / img1_h; - img2.width = image2.GetWidth(); - img2.height = image2.GetHeight(); - img2.ratio = img2.width / img2.height; + local.img2_w = image2.GetWidth(); + local.img2_h = image2.GetHeight(); + local.img2_ratio = img2_w / img2_h; - if (img1.ratio == 1 || (img1.width < 200 && img1.height < 200)) { - img1.scaled = image1.Scale(img2.width, img2.height); - return img1.scaled; + // Если изображение уже маленькое или квадратное — масштабируем напрямую + if (img1_ratio == 1 || (img1_w < 200 && img1_h < 200)) { + return image1.Scale(img2_w, img2_h); } - if (img1.width == img2.width && img1.height == img2.height) { + // Размеры совпадают — ничего не делаем + if (img2_w == img1_w && img2_h == img1_h) { return image1; } - if (img2.ratio < img1.ratio) { - factor = img2.height / img1.height; + // Сохраняем пропорции + local.factor; + if (img2_ratio < img1_ratio) { + factor = img2_h / img1_h; } else { - factor = img2.width / img1.width; + factor = img2_w / img1_w; } - img1.scaled = image1.Scale(img1.width * factor, img1.height * factor); - - return img1.scaled; + return image1.Scale(Math.Int(img1_w * factor), Math.Int(img1_h * factor)); }; FitIntoDimensions = fun(image1, image2) { - img1.width = image1.GetWidth(); - img1.height = image1.GetHeight(); + local.img1_w = image1.GetWidth(); + local.img1_h = image1.GetHeight(); - img2.width = image2.GetWidth(); - img2.height = image2.GetHeight(); + local.img2_w = image2.GetWidth(); + local.img2_h = image2.GetHeight(); - ma = Math.Max(img1.width, img2.height); - mi = Math.Min(img1.height, img2.height); - factor = ma / mi; + local.ma = Math.Max(img1_w, img1_h); + local.mi = Math.Min(img2_w, img2_h); + if (mi == 0) return image1; - img1.fit = image1.Scale(Math.Int(img1.width / factor), Math.Int(img1.height / factor)); + local.factor = ma / mi; + return image1.Scale(Math.Int(img1_w / factor), Math.Int(img1_h / factor)); }; SetSpriteImage = fun(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); + local.img = Image(asset); + sprite.SetImage(img); sprite.SetPosition(x, y, z); return sprite; }; +// Улучшенный blur: больше слоёв с меньшим смещением для более плавного эффекта Blur = fun(background_src, foreground_src, x, y, z, width, height, scale_width, scale_height) { - index = 0; - local.image[index]; + local.result = []; - 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); + // --- Фон (размытие через многослойное наложение) --- + local.bg_image = Image(background_src); + bg_image = ScaleImage(bg_image, Limit(scale_width, scale_height, 100)); + bg_image = bg_image.Crop(x, y, width, height); + bg_image = ScaleImage(bg_image, Limit(Percent(120, width), Percent(120, height), 100)); + bg_image = bg_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); + // Создаём 9 слоёв для более качественного размытия (3x3 сетка со смещением ±1) + local.blur_layers = [ + [-1, -1], [0, -1], [1, -1], + [-1, 0], [0, 0], [1, 0], + [-1, 1], [0, 1], [1, 1] + ]; - 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); + local.layer_opacity = 1.0 / 9.0; - 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++); + local.i; + for (i = 0; i < 9; i++) { + result[i].sprite = Sprite(bg_image); + result[i].sprite.SetOpacity(layer_opacity); + result[i].sprite.SetPosition( + x + blur_layers[i][0], + y + blur_layers[i][1], + z + i + ); + } - 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++); + // --- Передний план --- + local.fg_image = Image(foreground_src); + fg_image = fg_image.Scale(width, height); + result[9].sprite = Sprite(fg_image); + result[9].sprite.SetOpacity(0.75); + result[9].sprite.SetPosition(x, y, z + 9); - return local.image; + return result; }; +// ============================================================ +// ШРИФТЫ И ТЕКСТ (масштабируются от высоты экрана) +// ============================================================ -// TEXT -common_font = "Noto Sans Mono Regular 10"; -progress_font = "Noto Sans Mono Regular 12"; -link_font = "Noto Sans Italic 16"; +screen.width = Window.GetMaxWidth(); +screen.height = Window.GetMaxHeight(); + +aspect_ratio = screen.width / screen.height; + +// Базовый размер шрифта зависит от высоты экрана +base_font_size = Math.Max(Math.Int(screen.height / 110), 10); +if (base_font_size > 32) base_font_size = 32; + +common_font = "Noto Sans Mono Regular " + base_font_size; +progress_font = "Noto Sans Mono Regular " + Math.Int(base_font_size * 1.2); +link_font = "Noto Sans Italic " + Math.Int(base_font_size * 1.2); 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(); // ширина символа +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(); // ширина символа +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(); // ширина символа +link_symbol.height = link_symbol.image.GetHeight(); +link_symbol.width = link_symbol.image.GetWidth(); -starting_text = "Starting up..."; +starting_text = "Starting up…"; bye_text = "System is shutting down"; -progress_t= 0; - -// x0 = Window.GetX(); -// y0 = Window.GetY(); -// z0 = Window.GetZ(); +progress_t = 0; x0 = 0; y0 = 0; @@ -176,11 +190,18 @@ z0 = 0; Window.SetBackgroundTopColor(0, 0, 0); Window.SetBackgroundBottomColor(0, 0, 0); -screen.width = Window.GetMaxWidth(); -screen.height = Window.GetMaxHeight(); +// ============================================================ +// ФОН +// ============================================================ + +if (aspect_ratio == 3440 / 1440) { + background.image = Image("0EkLvkiE_4g_3440x1440.png"); +} else if (aspect_ratio == 1920 / 1080) { + background.image = Image("0EkLvkiE_4g_2564x1440.png"); +} else { + background.image = Image("BACKGROUND.png"); +} -// BACKGROUND -background.image = Image("BACKGROUND.png"); background.image = ScaleImage(background.image, Limit(screen.width, screen.height, 100)); background.width = background.image.GetWidth(); @@ -189,96 +210,89 @@ 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 = Sprite(); background.sprite.SetImage(background.image); background.sprite.SetOpacity(1); background.sprite.SetPosition(background.x, background.y, 0); -// SIDE BACKGROUND +// ============================================================ +// БОКОВАЯ ПАНЕЛЬ (BLUR) +// ============================================================ + 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.width = Percent(25, 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); +blur_result = 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 +); + +// ============================================================ +// БЛОК СООБЩЕНИЙ +// ============================================================ + +side_block.width = 0; +side_block.height = 0; -// 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.image = messages_box.image.Scale( + Percent(80, side_panel.width), + Percent(50, 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.x = Percent(50, side_panel.width) - Percent(50, messages_box.width); +// messages_box.y = Percent(aspect_ratio, side_panel.height); +messages_box.y = 0; 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_block.width = messages_box.width; +side_block.height = messages_box.height; -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.image = progress_form.image.Scale( + Percent(80, side_panel.width), + Percent(15, 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.x = Percent(50, side_panel.width) - Percent(50, progress_form.width); +progress_form.y = messages_box.y + messages_box.height + Percent(aspect_ratio, side_panel.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 +side_block.height = side_block.height + Percent(aspect_ratio, side_panel.height) + progress_form.height; + +// ============================================================ +// СПИННЕР +// ============================================================ + spinner.image = Image("SPINNER.png"); -spinner.image = spinner.image.Scale(Percent(1, screen.width), Percent(1, screen.width)); +spinner.image = spinner.image.Scale( + Percent(1, screen.width), + Percent(1, screen.width) +); spinner.width = spinner.image.GetWidth(); spinner.height = spinner.image.GetHeight(); @@ -287,24 +301,33 @@ spinner.x = progress_form.x + progress_form.width - Percent(10, progress_form.wi spinner.y = progress_form.y + Percent(10, progress_form.height); spinner.sprite = Sprite(spinner.image); -spinner.sprite.SetPosition(spinner.x, spinner.y, 13); // позиция за или перед +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.x = progress_form.x + Percent(5, progress_form.width); +progress_text.y = progress_form.y + Percent(10, progress_form.height); -progress_text.sprite = SpriteNew(); +progress_text.sprite = Sprite(); +progress_text.sprite.SetImage(progress_text.image); 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.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(); @@ -315,9 +338,15 @@ progress_box.y = progress_form.y + (progress_form.height - progress_box.height) 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.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(); @@ -328,26 +357,42 @@ progress_bar.y = progress_form.y + (progress_form.height - progress_bar.original progress_bar.sprite = Sprite(); progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 14); -// PROGRESS FADE +// ============================================================ +// 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.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; +// Глобальные переменные анимации fade +counter = 0; +fade_dir = 0; // 0 = вправо, 1 = влево + +// ============================================================ +// CALLBACK: ПРОГРЕСС ЗАГРУЗКИ +// ============================================================ fun 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()); + local.new_width = Math.Int(progress_bar.original_image.GetWidth() * progress); + + if (progress_bar.image.GetWidth() != new_width) { + progress_bar.image = progress_bar.original_image.Scale( + new_width, + 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); + local.f = Math.Int(progress * 100); progress_t.image = Image.Text(f + "%", 0.5, 0.5, 0.5, 1, progress_font); progress_text.sprite.SetImage(progress_t.image); } @@ -355,70 +400,82 @@ fun progress_callback(duration, progress) { Plymouth.SetBootProgressFunction(progress_callback); +// ============================================================ +// DIALOG: ЗАПРОС ПАРОЛЯ +// ============================================================ -// DIALOG status = "normal"; -//count = 0; +box_form.image = Image("BOX.png"); +box_form.image = box_form.image.Scale( + Percent(80, side_panel.width), + Percent(20, side_panel.height) +); + +box_form.width = box_form.image.GetWidth(); +box_form.height = box_form.image.GetHeight(); + +box_form.x = Percent(50, side_panel.width) - Percent(50, box_form.width); +box_form.y = progress_form.y + progress_form.height + Percent(aspect_ratio, side_panel.height); +box_form.z = 10000; + +box_form.sprite = Sprite(box_form.image); +box_form.sprite.SetPosition(box_form.x, box_form.y, box_form.z); +box_form.sprite.SetOpacity(0); fun dialog_setup() { - local.box_form; + local.box_form = global.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.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.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.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.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); - + hint.sprite = Sprite(); + hint.x = entry.x; + hint.y = box_form.y + Percent(5, box_form.height); + hint.z = box_form.z + 1; + hint.sprite.SetPosition(hint.x, hint.y, hint.z); bullet_i.image = Image("BULLET.png"); - bullet_i.image = bullet_i.image.Scale(Percent(50, entry.height), Percent(50, entry.height)); + 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; @@ -427,36 +484,56 @@ fun dialog_setup() { dialog_opacity(1); } - fun dialog_opacity(opacity) { if (opacity == 0) { dialog.box_form.sprite.SetOpacity(opacity); dialog.lock.sprite.SetOpacity(opacity); dialog.entry.sprite.SetOpacity(opacity); - } - else { + } else { + box_form.sprite.SetOpacity(opacity); dialog.lock.sprite.SetOpacity(opacity); dialog.entry.sprite.SetOpacity(opacity); } dialog.hint.sprite.SetOpacity(opacity); + local.index; for (index = 0; dialog.bullet[index]; index++) { dialog.bullet[index].sprite.SetOpacity(opacity); } } +// ============================================================ +// Изменение позиции интерфейса исходя из его общей высоты +// ============================================================ +side_block.height = side_block.height + Percent(aspect_ratio, side_panel.height) + box_form.height; +yyy = (side_panel.height - side_block.height) / 2; + +messages_box.y = messages_box.y + yyy; +progress_form.y = progress_form.y + yyy; +spinner.y = spinner.y + yyy; +progress_text.y = progress_text.y + yyy; +progress_box.y = progress_box.y + yyy; +progress_bar.y = progress_bar.y + yyy; +box_form.y = box_form.y + yyy; + +messages_box.sprite.SetPosition(messages_box.x, messages_box.y, 12); +progress_form.sprite.SetPosition(progress_form.x, progress_form.y, 12); +spinner.sprite.SetPosition(spinner.x, spinner.y, 13); +progress_text.sprite.SetPosition(progress_text.x, progress_text.y, 13); +progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 13); +progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 14); +box_form.sprite.SetPosition(box_form.x, box_form.y, box_form.z); +// ============================================================ fun display_normal_callback() { global.status = "normal"; - if (global.dialog) dialog_opacity(0); } Plymouth.SetDisplayNormalFunction(display_normal_callback); - fun display_password_callback(prompt_text, bullets) { global.status = "password"; @@ -465,22 +542,19 @@ fun display_password_callback(prompt_text, bullets) { else dialog_opacity(1); - padding_top_bottom = Percent(10, dialog.box_form.height); // отступы сверху и снизу - padding_left_right = Percent(5, dialog.box_form.width); // отступы слева и справа + local.padding_top_bottom = Percent(10, dialog.box_form.height); + local.padding_left_right = Percent(5, dialog.box_form.width); - LINE_WIDTH = 100; + local.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; - } + while ((LINE_WIDTH * common_symbol.width) > (dialog.box_form.width - (padding_left_right * 2))) { + LINE_WIDTH = LINE_WIDTH - 1; } - str_len = StringLength(prompt_text); + local.str_len = StringLength(prompt_text); + local.line_count = 0; + local.i; for (i = 1; LINE_WIDTH * i <= str_len; i++) { line_count = i; } @@ -492,10 +566,10 @@ fun display_password_callback(prompt_text, bullets) { } i = 1; - start = 0; - end = LINE_WIDTH; + local.start = 0; + local.end = LINE_WIDTH; - text = ""; + local.text = ""; for (i = 1; i <= line_count; i++) { text += prompt_text.SubString(start, end); @@ -504,9 +578,8 @@ fun display_password_callback(prompt_text, bullets) { start = end; if (LINE_WIDTH * i < str_len) { end = end + LINE_WIDTH; - } - else { - end = str_len - 1; + } else { + end = str_len; } } @@ -514,14 +587,21 @@ fun display_password_callback(prompt_text, bullets) { dialog.hint.image = Image.Text(prompt_text, 0.5, 0.5, 0.5, 1, common_font); dialog.hint.sprite.SetImage(dialog.hint.image); + // Важно: обновляем позицию после смены изображения + dialog.hint.sprite.SetPosition(dialog.hint.x, dialog.hint.y, dialog.hint.z); + local.index; 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].x = dialog.entry.x + index * dialog.bullet_i.width / 0.9 - dialog.entry.height * -0.2; 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); + 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); @@ -532,65 +612,115 @@ fun display_password_callback(prompt_text, bullets) { Plymouth.SetDisplayPasswordFunction(display_password_callback); +// ============================================================ +// ГЛАВНЫЙ ЛОГОТИП +// ============================================================ + +logo.image = Image("MAIN_LOGO.png"); +logo.image = FitIntoDimensions(logo.image, Limit(screen.width, screen.height, 15)); + +logo.width = logo.image.GetWidth(); +logo.height = logo.image.GetHeight(); + +logo.sprite = Sprite(logo.image); + +logo.x = screen.width - logo.image.GetWidth() - messages_box.x; +logo.y = yyy; +logo.sprite.SetOpacity(1); +logo.sprite.SetPosition(logo.x, 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 = logo.x + logo.width / 2 - project_link.width / 2; +project_link.y = logo.y + logo.height + Percent(aspect_ratio, screen.height); + +project_link.sprite.SetOpacity(1); +project_link.sprite.SetPosition(project_link.x, project_link.y, 15); + +// ============================================================ +// REFRESH: ОСНОВНОЙ ЦИКЛ АНИМАЦИИ +// ============================================================ time = 1; +// FSCK переменные (для совместимости с Plymouth API) +fsck_running = 0; +fsck_done_fading = 0; +fsck_fade_in_counter = 0; +fsck_progress_meter_sprite = Sprite(); +fsck_progress_fade_sprite = Sprite(); + fun 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); + // Показываем/скрываем элементы в зависимости от режима + if (global.status == "normal" && Plymouth.GetMode() == "boot") { + progress_fade.sprite.SetOpacity(0); + progress_bar.sprite.SetOpacity(1); + + local.text_img = Image.Text(starting_text, 0.5, 0.5, 0.5, 1, common_font); + local.text_spr = Sprite(text_img); + text_spr.SetPosition( + progress_box.x, + progress_box.y - progress_text.image.GetHeight() * 2, + 13 + ); + } else { + progress_fade.sprite.SetOpacity(1); + progress_bar.sprite.SetOpacity(0); + + local.text_end_img = Image.Text(bye_text, 0.5, 0.5, 0.5, 1, common_font); + local.text_end_spr = Sprite(text_end_img); + text_end_spr.SetPosition( + progress_box.x, + progress_box.y - progress_text.image.GetHeight() * 2, + 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); + // Анимация fade-полоски + progress_fade.sprite.SetPosition( + counter + progress_bar.x, + progress_bar.y, + 14 + ); if (fade_dir == 0) { counter++; if (counter >= max_counter) { fade_dir = 1; } - } - else { + } 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) { + // Скрываем спиннер при fsck или запросе пароля + if (fsck_running == 1 || (global.dialog && dialog.hint.sprite.GetOpacity() == 1)) { spinner.sprite.SetOpacity(0); - } - else { + } else { spinner.sprite.SetOpacity(1); time++; - theta = time / (Math.Pi * 2); + local.theta = time / (Math.Pi * 2); spinner.sprite.SetImage(spinner.image.Rotate(theta)); } + // FSCK анимация плавного появления 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_fade_in_counter += 0.025; + } else { fsck_done_fading = 1; } } @@ -598,8 +728,11 @@ fun refreshHandler() { Plymouth.SetRefreshFunction(refreshHandler); +// ============================================================ +// CALLBACK: ОДИНОЧНОЕ СООБЩЕНИЕ +// ============================================================ -message_status.sprite = SpriteNew(); +message_status.sprite = Sprite(); fun message_callback(prompt_text) { message_status.image = Image.Text(prompt_text, 0.5, 0.5, 0.5, 1, common_font); @@ -613,82 +746,75 @@ fun message_callback(prompt_text) { 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%) +local.padding_top_bottom = Percent(10, messages_box.height); +local.padding_left_right = Percent(5, messages_box.width); -// высота символа = 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 +message_sprite_.x = messages_box.x + padding_left_right; +message_sprite_.y = messages_box.y + padding_top_bottom; -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 +NUM_SCROLL_LINES = 100; +LINE_WIDTH_LOG = 100; +LINE_HEIGHT = common_symbol.height * 1.5; +// Подстраиваем количество строк под высоту блока сообщений +local.index; 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 { + 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 { +// Подстраиваем ширину строки под ширину блока сообщений +for (index = LINE_WIDTH_LOG; index > 0; index--) { + if ((LINE_WIDTH_LOG * common_symbol.width) > (messages_box.width - (padding_left_right * 2))) { + LINE_WIDTH_LOG = LINE_WIDTH_LOG - 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); -} //высота строк //отступ строк - +// Инициализация спрайтов для каждой строки лога +local.i; +for (i = 0; i < NUM_SCROLL_LINES; i++) { + lines[i] = Image.Text("", 0.5, 0.5, 0.5, 1, common_font); + message_sprite[i] = Sprite(); + message_sprite[i].SetPosition( + message_sprite_.x, + message_sprite_.y + (i * LINE_HEIGHT), + 13 + ); +} fun StringLength(string) { - index = 0; - str = String(string); - while(str.CharAt(index)) index++; + local.index = 0; + local.str = String(string); + while (str.CharAt(index)) index++; return index; } - fun scroll_message_callback(text) { - // Truncate the message if too long - if (StringLength(text) > LINE_WIDTH) { - text = text.SubString(0, LINE_WIDTH - 3); - text += "..."; + // Обрезаем слишком длинные сообщения + if (StringLength(text) > LINE_WIDTH_LOG) { + text = text.SubString(0, LINE_WIDTH_LOG - 1); + text += "…"; } - // Shift message one up + // Сдвигаем все сообщения вверх на одну строку + local.i; for (i = 0; i < NUM_SCROLL_LINES - 1; i++) { - lines[i] = lines[i+1]; + 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]); } @@ -696,11 +822,13 @@ fun scroll_message_callback(text) { Plymouth.SetUpdateStatusFunction(scroll_message_callback); +// ============================================================ +// CALLBACK: ЗАВЕРШЕНИЕ +// ============================================================ -// QUIT fun quit_callback() { - progress_fade.sprite.SetOpacity (1); - progress_bar.sprite.SetOpacity (0); + progress_fade.sprite.SetOpacity(1); + progress_bar.sprite.SetOpacity(0); if (Plymouth.GetMode() == "shutdown") { logo.sprite.SetOpacity(0); }