Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 137 additions & 5 deletions src/gui/screen_printing_serial.cpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,161 @@
#include "screen_printing_serial.hpp"
#include "config.h"
#include "marlin_client.hpp"
#include <marlin_server_shared.h>
#include "filament.hpp"
#include "i18n.h"
#include "ScreenHandler.hpp"
#include "odometer.hpp"
#include "config_features.h"
#include "window_icon.hpp"
#include "screen_menu_tune.hpp"
#include "img_resources.hpp"
#include "print_time_module.hpp"
#include <serial_printing.hpp>
#include <guiconfig/GuiDefaults.hpp>
#include <feature/print_status_message/print_status_message_mgr.hpp>
#include <feature/print_status_message/print_status_message_formatter_buddy.hpp>
#include <utils/string_builder.hpp>

#if ENABLED(CRASH_RECOVERY)
#include "../Marlin/src/feature/prusa/crash_recovery.hpp"
#endif

// Layout constants for the serial printing screen
// Note: Buttons start at Y=185, so content must end before that
namespace {
constexpr int16_t MARGIN_X = 30;
constexpr int16_t COL_W = 200; // Width of each column

constexpr int16_t PROGRESS_BAR_Y = 50;
constexpr int16_t PROGRESS_BAR_H = 16;

// Row 1: Progress % (centered)
constexpr int16_t ROW1_LABEL_Y = 68;
constexpr int16_t ROW1_VALUE_Y = 84;

// Row 2: Elapsed | Remaining
constexpr int16_t ROW2_LABEL_Y = 110;
constexpr int16_t ROW2_VALUE_Y = 126;

constexpr int16_t LABEL_H = 16;
constexpr int16_t VALUE_H = 22;

// Status message (needs H=20 for proper rendering)
constexpr int16_t MESSAGE_Y = 155;
constexpr int16_t MESSAGE_H = 20;
} // namespace

screen_printing_serial_data_t::screen_printing_serial_data_t()
: ScreenPrintingModel(_(caption))
, octo_icon(this, Rect16((GuiDefaults::ScreenWidth - img::serial_printing_172x138.w) / 2, GuiDefaults::RectScreenBody.Top(), img::serial_printing_172x138.w, img::serial_printing_172x138.h), &img::serial_printing_172x138)
, w_progress(this, Rect16(MARGIN_X, PROGRESS_BAR_Y, GuiDefaults::ScreenWidth - 2 * MARGIN_X, PROGRESS_BAR_H))
// Row 1: Progress % (centered)
, w_progress_label(this, Rect16(0, ROW1_LABEL_Y, GuiDefaults::ScreenWidth, LABEL_H), is_multiline::no)
, w_progress_value(this, Rect16(0, ROW1_VALUE_Y, GuiDefaults::ScreenWidth, VALUE_H), is_multiline::no)
// Row 2: Elapsed (left) | Remaining (right)
, w_elapsed_label(this, Rect16(MARGIN_X, ROW2_LABEL_Y, COL_W, LABEL_H), is_multiline::no)
, w_elapsed_value(this, Rect16(MARGIN_X, ROW2_VALUE_Y, COL_W, VALUE_H), is_multiline::no)
, w_remaining_label(this, Rect16(GuiDefaults::ScreenWidth - MARGIN_X - COL_W, ROW2_LABEL_Y, COL_W, LABEL_H), is_multiline::no)
, w_remaining_value(this, Rect16(GuiDefaults::ScreenWidth - MARGIN_X - COL_W, ROW2_VALUE_Y, COL_W, VALUE_H), is_multiline::no)
// Buffers
, elapsed_buffer()
, progress_buffer()
, remaining_buffer()
, w_message(this, Rect16(MARGIN_X, MESSAGE_Y, GuiDefaults::ScreenWidth - 2 * MARGIN_X, MESSAGE_H), is_multiline::no)
, message_text()
, current_message()
, last_tick(0)
, connection(connection_state_t::connected)
, last_state(marlin_server::State::Aborted) {
ClrMenuTimeoutClose();
SetOnSerialClose();

octo_icon.Disable();
octo_icon.Unshadow();
// Row 1: Progress %
w_progress_label.SetText(_("Progress"));
w_progress_label.SetAlignment(Align_t::Center());
w_progress_label.set_font(Font::small);
w_progress_label.SetTextColor(COLOR_SILVER);
w_progress_value.SetAlignment(Align_t::Center());
w_progress_value.set_font(Font::big);
strlcpy(progress_buffer.data(), "0%", progress_buffer.size());
w_progress_value.SetText(string_view_utf8::MakeRAM(progress_buffer.data()));

// Row 2 left: Elapsed
w_elapsed_label.SetText(_("Elapsed"));
w_elapsed_label.SetAlignment(Align_t::Center());
w_elapsed_label.set_font(Font::small);
w_elapsed_label.SetTextColor(COLOR_SILVER);
w_elapsed_value.SetAlignment(Align_t::Center());
w_elapsed_value.set_font(Font::big);
strlcpy(elapsed_buffer.data(), "0:00:00", elapsed_buffer.size());
w_elapsed_value.SetText(string_view_utf8::MakeRAM(elapsed_buffer.data()));

// Row 2 right: Remaining
w_remaining_label.SetText(_("Remaining"));
w_remaining_label.SetAlignment(Align_t::Center());
w_remaining_label.set_font(Font::small);
w_remaining_label.SetTextColor(COLOR_SILVER);
w_remaining_value.SetAlignment(Align_t::Center());
w_remaining_value.set_font(Font::big);
strlcpy(remaining_buffer.data(), "--:--", remaining_buffer.size());
w_remaining_value.SetText(string_view_utf8::MakeRAM(remaining_buffer.data()));

// Setup status message
w_message.SetAlignment(Align_t::Center());
w_message.set_font(Font::small);
w_message.SetTextColor(COLOR_ORANGE);
message_text[0] = '\0';
w_message.SetText(string_view_utf8::MakeRAM(message_text.data()));

SetButtonIconAndLabel(BtnSocket::Right, BtnRes::Disconnect, LabelRes::Stop);
}

void screen_printing_serial_data_t::updateTimes() {
uint32_t duration = marlin_vars().print_duration.get();

// Update progress percentage
uint8_t percent = marlin_vars().sd_percent_done.get();
snprintf(progress_buffer.data(), progress_buffer.size(), "%d%%", percent);
w_progress_value.SetText(string_view_utf8::MakeRAM(progress_buffer.data()));
w_progress_value.Invalidate();

// Update elapsed time
PrintTime::print_formatted_duration(duration, elapsed_buffer, true);
w_elapsed_value.SetText(string_view_utf8::MakeRAM(elapsed_buffer.data()));
w_elapsed_value.Invalidate();

// Update remaining time from M73
uint32_t time_to_end = marlin_vars().time_to_end.get();
if (time_to_end != marlin_server::TIME_TO_END_INVALID) {
PrintTime::print_formatted_duration(time_to_end, remaining_buffer, true);
} else {
strlcpy(remaining_buffer.data(), "--:--", remaining_buffer.size());
}
w_remaining_value.SetText(string_view_utf8::MakeRAM(remaining_buffer.data()));
w_remaining_value.Invalidate();
}

void screen_printing_serial_data_t::updateStatusMessage() {
const auto new_msg = print_status_message().current_message();
if (new_msg.message != current_message.message) {
if (new_msg) {
// Format the new message
std::array<char, 64> new_text;
StringBuilder sb(new_text);
PrintStatusMessageFormatterBuddy::format(sb, new_msg.message);
if (strcmp(message_text.data(), new_text.data()) != 0) {
strlcpy(message_text.data(), new_text.data(), message_text.size());
w_message.SetText(string_view_utf8::MakeRAM(message_text.data()));
w_message.Invalidate();
}
} else {
// Clear message
message_text[0] = '\0';
w_message.SetText(string_view_utf8::MakeRAM(message_text.data()));
w_message.Invalidate();
}
current_message = new_msg;
}
}

void screen_printing_serial_data_t::windowEvent(window_t *sender, GUI_event_t event, void *param) {
marlin_server::State state = marlin_vars().print_state;

Expand All @@ -54,6 +180,12 @@ void screen_printing_serial_data_t::windowEvent(window_t *sender, GUI_event_t ev
last_state = state;
}

// Update displays on each loop iteration
if (event == GUI_event_t::LOOP) {
updateTimes();
updateStatusMessage();
}

ScreenPrintingModel::windowEvent(sender, event, param);
}

Expand Down
28 changes: 27 additions & 1 deletion src/gui/screen_printing_serial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,35 @@
#include "window_header.hpp"
#include "status_footer.hpp"
#include "window_text.hpp"
#include "window_print_progress.hpp"
#include <feature/print_status_message/print_status_message.hpp>
#include <array>

class screen_printing_serial_data_t : public ScreenPrintingModel {
static constexpr const char *caption = N_("SERIAL PRINTING");

window_icon_t octo_icon;
// Progress bar
WindowPrintProgress w_progress;

// Row 1: Progress % (centered)
window_text_t w_progress_label;
window_text_t w_progress_value;

// Row 2: Elapsed (left) | Remaining (right)
window_text_t w_elapsed_label;
window_text_t w_elapsed_value;
window_text_t w_remaining_label;
window_text_t w_remaining_value;

// Buffers
std::array<char, 32> elapsed_buffer;
std::array<char, 8> progress_buffer;
std::array<char, 32> remaining_buffer;

// Status message display
window_text_t w_message;
std::array<char, 64> message_text;
PrintStatusMessageRecord current_message;

int last_tick;
enum class connection_state_t { connected,
Expand All @@ -22,6 +45,9 @@ class screen_printing_serial_data_t : public ScreenPrintingModel {

marlin_server::State last_state;

void updateTimes();
void updateStatusMessage();

public:
screen_printing_serial_data_t();

Expand Down