Prusa MINI Firmware overview
screen_print_preview.c File Reference
#include "screen_print_preview.h"
#include "dbg.h"
#include "ff.h"
#include "gcode_file.h"
#include "gui.h"
#include "marlin_client.h"
#include "resource.h"
#include "screen_printing.h"
#include "window_dlg_load.h"
#include "filament_sensor.h"
#include <stdarg.h>
#include <stdbool.h>

Classes

struct  description_line_t
 
struct  screen_print_preview_data_t
 

Macros

#define DBG   _dbg0
 
#define HEADER_HEIGHT   24
 
#define PADDING   10
 
#define SCREEN_WIDTH   240
 
#define SCREEN_HEIGHT   320
 
#define THUMBNAIL_HEIGHT   124
 
#define TITLE_HEIGHT   24
 
#define LINE_HEIGHT   15
 
#define LINE_SPACING   5
 
#define BACK_BUTTON_ID   0x11
 
#define PRINT_BUTTON_ID   0x12
 
#define pd   ((screen_print_preview_data_t *)screen->pdata)
 
#define name_equals(str)   (!strncmp(name_buffer, str, sizeof(name_buffer)))
 

Functions

static void screen_print_preview_init (screen_t *screen)
 
static void screen_print_preview_done (screen_t *screen)
 
static void screen_print_preview_draw (screen_t *screen)
 
static int screen_print_preview_event (screen_t *screen, window_t *window, uint8_t event, void *param)
 
void screen_print_preview_set_gcode_filepath (const char *fpath)
 
const char * screen_print_preview_get_gcode_filepath ()
 
void screen_print_preview_set_gcode_filename (const char *fname)
 
void screen_print_preview_set_on_action (print_preview_action_handler_t handler)
 
static void initialize_description_line (screen_t *screen, int idx, int y_pos, const char *title, const char *value_fmt,...)
 
static void initialize_description_lines (screen_t *screen, int y)
 
static void initialize_gcode_file (screen_t *screen)
 
static bool gcode_file_exists (screen_t *screen)
 

Variables

static const char * gcode_file_name = NULL
 
static const char * gcode_file_path = NULL
 
static print_preview_action_handler_t action_handler = NULL
 
static screen_t screen_print_preview
 
const uint16_t menu_icons [2]
 
screen_t *const pscreen_print_preview = &screen_print_preview
 
static int suppress_draw = 0
 

Macro Definition Documentation

◆ DBG

#define DBG   _dbg0

◆ HEADER_HEIGHT

#define HEADER_HEIGHT   24

◆ PADDING

#define PADDING   10

◆ SCREEN_WIDTH

#define SCREEN_WIDTH   240

◆ SCREEN_HEIGHT

#define SCREEN_HEIGHT   320

◆ THUMBNAIL_HEIGHT

#define THUMBNAIL_HEIGHT   124

◆ TITLE_HEIGHT

#define TITLE_HEIGHT   24

◆ LINE_HEIGHT

#define LINE_HEIGHT   15

◆ LINE_SPACING

#define LINE_SPACING   5

◆ BACK_BUTTON_ID

#define BACK_BUTTON_ID   0x11

◆ PRINT_BUTTON_ID

#define PRINT_BUTTON_ID   0x12

◆ pd

#define pd   ((screen_print_preview_data_t *)screen->pdata)

◆ name_equals

#define name_equals (   str)    (!strncmp(name_buffer, str, sizeof(name_buffer)))

Function Documentation

◆ screen_print_preview_init()

static void screen_print_preview_init ( screen_t screen)
static
222  {
224  initialize_gcode_file(screen);
225 
227  rect_ui16(0, 0, 0, 0), &pd->frame);
229  int y = PADDING;
230 
231  // Title
232  int title_text_id = window_create_ptr(
235  &pd->title_text);
236  pd->title_text.font = resource_font(IDR_FNT_BIG);
237  window_set_text(title_text_id, gcode_file_name);
238  y += TITLE_HEIGHT + PADDING;
239 
240  // Thumbnail
241  if (pd->gcode_has_thumbnail) {
242  y += THUMBNAIL_HEIGHT + PADDING;
243  // Drawing is done in screen_print_preview_event func
244  pd->redraw_thumbnail = true;
245  }
246 
247  // Description lines
248  initialize_description_lines(screen, y);
249 
250  // Print and Back buttons
251  y = SCREEN_HEIGHT - PADDING - LINE_HEIGHT - 64;
252  int print_button_id = window_create_ptr(WINDOW_CLS_ICON, window_id,
253  rect_ui16(PADDING, y, 64, 64), &pd->print_button);
254  window_set_color_back(print_button_id, COLOR_GRAY);
256  window_set_tag(print_button_id, PRINT_BUTTON_ID);
257  window_enable(print_button_id);
258  int back_button_id = window_create_ptr(
260  rect_ui16(SCREEN_WIDTH - PADDING - 64, y, 64, 64), &pd->back_button);
261  window_set_color_back(back_button_id, COLOR_GRAY);
263  window_set_tag(back_button_id, BACK_BUTTON_ID);
264  window_enable(back_button_id);
265 
266  // Print and Back labels
267  y += 64;
268  int print_label_id = window_create_ptr(
270  &pd->print_label);
271  window_set_text(print_label_id, "print");
272  window_set_alignment(print_label_id, ALIGN_CENTER);
273  pd->print_label.font = resource_font(IDR_FNT_SMALL);
274  int back_label_id = window_create_ptr(
276  rect_ui16(SCREEN_WIDTH - PADDING - 64, y, 64, LINE_HEIGHT),
277  &pd->back_label);
278  window_set_text(back_label_id, "back");
279  window_set_alignment(back_label_id, ALIGN_CENTER);
280  pd->back_label.font = resource_font(IDR_FNT_SMALL);
281 }
Here is the call graph for this function:

◆ screen_print_preview_done()

static void screen_print_preview_done ( screen_t screen)
static
283  {
284  if (pd->gcode_file_opened) {
285  f_close(&pd->gcode_file);
286  pd->gcode_file_opened = false;
287  pd->gcode_has_thumbnail = false;
288  }
289  window_destroy(pd->frame.win.id);
290 }
Here is the call graph for this function:

◆ screen_print_preview_draw()

static void screen_print_preview_draw ( screen_t screen)
static
292  {
293 }

◆ screen_print_preview_event()

static int screen_print_preview_event ( screen_t screen,
window_t window,
uint8_t  event,
void param 
)
static
305  {
306  // In case the file is no longer present, close this screen.
307  // (Most likely because of usb flash drive disconnection).
308  if (!gcode_file_exists(screen)) {
309  screen_close();
310  return 0;
311  }
312 
314  suppress_draw = 1;
315  const char *btns[3] = { "YES", "NO", "IGNORE" };
316  switch (gui_msgbox_ex(0,
317  "Filament not detected. Load filament now? Select NO to cancel, or IGNORE to disable the filament sensor and continue.",
320  0, btns)) {
321  case MSGBOX_RES_CUSTOM0: //YES - load
323  break;
324  case MSGBOX_RES_CUSTOM1: //NO - cancel
325  if (action_handler) {
327  }
328  suppress_draw = 0;
329  return 1;
330  case MSGBOX_RES_CUSTOM2: //IGNORE - disable
331  fs_disable();
332  break;
333  }
334  suppress_draw = 0;
335  window_draw(pd->frame.win.id);
336  }
337 
338  if (!suppress_draw && event == WINDOW_EVENT_LOOP && pd->gcode_has_thumbnail &&
339  // Draw the thumbnail
340  pd->redraw_thumbnail) {
341  FILE f = { 0 };
342  f_lseek(&pd->gcode_file, 0);
343  if (f_gcode_thumb_open(&f, &pd->gcode_file) == 0) {
344  display->draw_png(
347  } else {
348  DBG("print preview: f_gcode_thumb_open returned non-zero value");
349  }
350  pd->redraw_thumbnail = false;
351  } else if (event == WINDOW_EVENT_CLICK && (intptr_t)param == PRINT_BUTTON_ID) {
352  if (action_handler) {
354  return 1;
355  }
356  } else if (event == WINDOW_EVENT_CLICK && (intptr_t)param == BACK_BUTTON_ID) {
357  if (action_handler) {
359  return 1;
360  }
361  }
362 
363  return 0;
364 }
Here is the call graph for this function:

◆ screen_print_preview_set_gcode_filepath()

void screen_print_preview_set_gcode_filepath ( const char *  fpath)
81  {
82  gcode_file_path = fpath;
83 }
Here is the caller graph for this function:

◆ screen_print_preview_get_gcode_filepath()

const char * screen_print_preview_get_gcode_filepath ( )
85  {
86  return gcode_file_path;
87 }
Here is the caller graph for this function:

◆ screen_print_preview_set_gcode_filename()

void screen_print_preview_set_gcode_filename ( const char *  fname)
89  {
90  gcode_file_name = fname;
91 }
Here is the caller graph for this function:

◆ screen_print_preview_set_on_action()

void screen_print_preview_set_on_action ( print_preview_action_handler_t  handler)
94  {
95  action_handler = handler;
96 }
Here is the caller graph for this function:

◆ initialize_description_line()

static void initialize_description_line ( screen_t screen,
int  idx,
int  y_pos,
const char *  title,
const char *  value_fmt,
  ... 
)
static
100  {
101  description_line_t *line = &pd->description_lines[idx];
102  int window_id = pd->frame.win.id;
103 
104  int title_width = strlen(title) * resource_font(IDR_FNT_SMALL)->w;
105  int title_id = window_create_ptr(
107  rect_ui16(PADDING, y_pos, title_width, LINE_HEIGHT), &line->title);
108  window_set_text(title_id, title);
110  window_set_padding(title_id, padding_ui8(0, 0, 0, 0));
112 
113  int value_width = SCREEN_WIDTH - PADDING * 2 - title_width - 1;
115  rect_ui16(SCREEN_WIDTH - PADDING - value_width, y_pos,
116  value_width, LINE_HEIGHT),
117  &line->value);
118  va_list args;
119  va_start(args, value_fmt);
120  vsnprintf(line->value_buffer, sizeof(line->value_buffer), value_fmt, args);
121  va_end(args);
122  window_set_text(value_id, line->value_buffer);
124  window_set_padding(value_id, padding_ui8(0, 0, 0, 0));
126 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_description_lines()

static void initialize_description_lines ( screen_t screen,
int  y 
)
static
128  {
129  int line_idx = 0;
130 
131  // print time
132  if (pd->gcode_printing_time[0]) {
133  initialize_description_line(screen, line_idx++, y, "print time", "%s",
134  pd->gcode_printing_time);
135  } else {
136  initialize_description_line(screen, line_idx++, y, "print time",
137  "unknown");
138  }
139  y += LINE_HEIGHT + LINE_SPACING;
140 
141  if (pd->gcode_has_thumbnail) {
142  // material
143  if (pd->gcode_filament_type[0] && pd->gcode_filament_used_mm && pd->gcode_filament_used_g) {
145  screen, line_idx++, y, "material", "%s/%u g/%0.2f m",
146  pd->gcode_filament_type, pd->gcode_filament_used_g,
147  (double)((float)pd->gcode_filament_used_mm / 1000.0F));
148  y += LINE_HEIGHT + LINE_SPACING;
149  }
150  } else {
151  // material
152  if (pd->gcode_filament_type[0]) {
153  initialize_description_line(screen, line_idx++, y, "material", "%s",
154  pd->gcode_filament_type);
155  y += LINE_HEIGHT + LINE_SPACING;
156  }
157  // used filament
158  if (pd->gcode_filament_used_mm && pd->gcode_filament_used_g) {
160  screen, line_idx++, y, "used filament", "%.2f m",
161  (double)((float)pd->gcode_filament_used_mm / 1000.0F));
162  y += LINE_HEIGHT + LINE_SPACING;
163 
164  initialize_description_line(screen, line_idx++, y, "", "%.0f g",
165  (double)pd->gcode_filament_used_g);
166  y += LINE_HEIGHT + LINE_SPACING;
167  }
168  }
169 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_gcode_file()

static void initialize_gcode_file ( screen_t screen)
static
171  {
172  memset(&pd->gcode_file, 1, sizeof(FIL));
173  pd->gcode_file_opened = false;
174  pd->gcode_has_thumbnail = false;
175 
176  // try to open the file first
177  if (!gcode_file_path || f_open(&pd->gcode_file, gcode_file_path, FA_READ) != FR_OK) {
178  return;
179  }
180  pd->gcode_file_opened = true;
181 
182  // thubnail presence check
183  {
184  FILE f = { 0 };
185  if (f_gcode_thumb_open(&f, &pd->gcode_file) == 0) {
186  char buffer;
187  pd->gcode_has_thumbnail = fread((void *)&buffer, 1, 1, &f) > 0;
189  }
190  }
191 
192  // find printing time and filament information
193  pd->gcode_printing_time[0] = 0;
194  pd->gcode_filament_type[0] = 0;
195  pd->gcode_filament_used_mm = 0;
196  pd->gcode_filament_used_g = 0;
197  const unsigned search_last_x_bytes = 10000;
198  FSIZE_t filesize = f_size(&pd->gcode_file);
199  f_lseek(&pd->gcode_file, filesize > search_last_x_bytes ? filesize - search_last_x_bytes : 0);
200  char name_buffer[64];
201  char value_buffer[32];
203  &pd->gcode_file, name_buffer, sizeof(name_buffer), value_buffer,
204  sizeof(value_buffer))) {
205 
206 #define name_equals(str) (!strncmp(name_buffer, str, sizeof(name_buffer)))
207 
208  if (name_equals("estimated printing time (normal mode)")) {
209  snprintf(pd->gcode_printing_time, sizeof(pd->gcode_printing_time),
210  "%s", value_buffer);
211  } else if (name_equals("filament_type")) {
212  snprintf(pd->gcode_filament_type, sizeof(pd->gcode_filament_type),
213  "%s", value_buffer);
214  } else if (name_equals("filament used [mm]")) {
215  sscanf(value_buffer, "%u", &pd->gcode_filament_used_mm);
216  } else if (name_equals("filament used [g]")) {
217  sscanf(value_buffer, "%u", &pd->gcode_filament_used_g);
218  }
219  }
220 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gcode_file_exists()

static bool gcode_file_exists ( screen_t screen)
static
295  {
296  FILINFO finfo = { 0 };
297  return f_stat(gcode_file_path, &finfo) == FR_OK;
298 }
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ gcode_file_name

const char* gcode_file_name = NULL
static

◆ gcode_file_path

const char* gcode_file_path = NULL
static

◆ action_handler

print_preview_action_handler_t action_handler = NULL
static

◆ screen_print_preview

◆ menu_icons

const uint16_t menu_icons[2]

◆ pscreen_print_preview

screen_t* const pscreen_print_preview = &screen_print_preview

◆ suppress_draw

int suppress_draw = 0
static
window_set_alignment
void window_set_alignment(int16_t id, uint8_t alignment)
Definition: window.c:561
f_gcode_thumb_close
int f_gcode_thumb_close(FILE *fp)
Definition: gcode_file.cpp:52
PADDING
#define PADDING
Definition: screen_print_preview.c:41
gcode_file_name
static const char * gcode_file_name
Definition: screen_print_preview.c:52
PRINT_PREVIEW_ACTION_PRINT
Definition: screen_print_preview.h:10
FIL
Definition: ff.h:155
PRINT_BUTTON_ID
#define PRINT_BUTTON_ID
Definition: screen_print_preview.c:50
SCREEN_WIDTH
#define SCREEN_WIDTH
Definition: screen_print_preview.c:42
initialize_description_line
static void initialize_description_line(screen_t *screen, int idx, int y_pos, const char *title, const char *value_fmt,...)
Definition: screen_print_preview.c:98
_rect_ui16_t::y
uint16_t y
Definition: guitypes.h:71
_rect_ui16_t::w
uint16_t w
Definition: guitypes.h:72
THUMBNAIL_HEIGHT
#define THUMBNAIL_HEIGHT
Definition: screen_print_preview.c:44
window_set_padding
void window_set_padding(int16_t id, padding_ui8_t padding)
Definition: window.c:549
TITLE_HEIGHT
#define TITLE_HEIGHT
Definition: screen_print_preview.c:45
f_stat
FRESULT f_stat(const TCHAR *path, FILINFO *fno)
Definition: ff.c:4412
IDR_PNG_menu_icon_stop
#define IDR_PNG_menu_icon_stop
Definition: resource.h:36
window_set_color_back
void window_set_color_back(int16_t id, color_t clr)
Definition: window.c:431
SCREEN_HEIGHT
#define SCREEN_HEIGHT
Definition: screen_print_preview.c:43
name_equals
#define name_equals(str)
LINE_HEIGHT
#define LINE_HEIGHT
Definition: screen_print_preview.c:46
MSGBOX_RES_CUSTOM1
#define MSGBOX_RES_CUSTOM1
Definition: window_msgbox.h:50
f_open
FRESULT f_open(FIL *fp, const TCHAR *path, BYTE mode)
Definition: ff.c:3296
ALIGN_CENTER
#define ALIGN_CENTER
Definition: guitypes.h:19
rect_ui16
static rect_ui16_t rect_ui16(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
Definition: guitypes.h:159
window_destroy
void window_destroy(int16_t id)
Definition: window.c:132
screen_print_preview_data_t
Definition: screen_print_preview.c:22
padding_ui8
static padding_ui8_t padding_ui8(uint8_t l, uint8_t t, uint8_t r, uint8_t b)
Definition: guitypes.h:164
DBG
#define DBG
Definition: screen_print_preview.c:14
f_gcode_get_next_comment_assignment
bool f_gcode_get_next_comment_assignment(FIL *fp, char *name_buffer, int name_buffer_len, char *value_buffer, int value_buffer_len)
Definition: gcode_file.cpp:94
_gui_defaults_t::msg_box_sz
rect_ui16_t msg_box_sz
Definition: guitypes.h:114
window_set_icon_id
void window_set_icon_id(int16_t id, uint16_t id_res)
Definition: window.c:659
description_line_t
Definition: screen_print_preview.c:16
FSIZE_t
DWORD FSIZE_t
Definition: ff.h:78
screen_print_preview_draw
static void screen_print_preview_draw(screen_t *screen)
Definition: screen_print_preview.c:292
NULL
#define NULL
Definition: usbd_def.h:53
ALIGN_LEFT_BOTTOM
#define ALIGN_LEFT_BOTTOM
Definition: guitypes.h:22
window_id
int16_t window_id(window_t *ptr)
Definition: window.c:86
screen_print_preview_done
static void screen_print_preview_done(screen_t *screen)
Definition: screen_print_preview.c:283
screen_close
void screen_close(void)
Definition: screen.c:80
PRINT_PREVIEW_ACTION_BACK
Definition: screen_print_preview.h:9
COLOR_GRAY
#define COLOR_GRAY
Definition: guitypes.h:50
ALIGN_RIGHT_BOTTOM
#define ALIGN_RIGHT_BOTTOM
Definition: guitypes.h:25
window_set_text
void window_set_text(int16_t id, const char *text)
Definition: window.c:340
description_line_t::title
window_text_t title
Definition: screen_print_preview.c:17
pd
#define pd
Definition: screen_print_preview.c:79
MSGBOX_RES_CUSTOM2
#define MSGBOX_RES_CUSTOM2
Definition: window_msgbox.h:51
suppress_draw
static int suppress_draw
Definition: screen_print_preview.c:302
FA_READ
#define FA_READ
Definition: ff.h:326
action_handler
static print_preview_action_handler_t action_handler
Definition: screen_print_preview.c:54
f_gcode_thumb_open
int f_gcode_thumb_open(FILE *fp, FIL *gcode_fp)
Definition: gcode_file.cpp:29
WINDOW_CLS_FRAME
#define WINDOW_CLS_FRAME
Definition: window.h:9
f_size
#define f_size(fp)
Definition: ff.h:280
BACK_BUTTON_ID
#define BACK_BUTTON_ID
Definition: screen_print_preview.c:49
reset_print_state
void reset_print_state(void)
Definition: screen_printing.cpp:131
initialize_gcode_file
static void initialize_gcode_file(screen_t *screen)
Definition: screen_print_preview.c:171
_font_t::w
uint8_t w
Definition: guitypes.h:77
_display_t::draw_png
display_draw_png_t * draw_png
Definition: display.h:37
MSGBOX_RES_CUSTOM0
#define MSGBOX_RES_CUSTOM0
Definition: window_msgbox.h:49
gcode_file_exists
static bool gcode_file_exists(screen_t *screen)
Definition: screen_print_preview.c:295
window_set_tag
void window_set_tag(int16_t id, uint8_t tag)
Definition: window.c:329
f_lseek
FRESULT f_lseek(FIL *fp, FSIZE_t ofs)
Definition: ff.c:4060
gui_dlg_load_forced
dlg_result_t gui_dlg_load_forced(void)
Definition: window_dlg_load.c:124
IDR_FNT_BIG
#define IDR_FNT_BIG
Definition: resource.h:11
display
display_t * display
Definition: display.c:6
WINDOW_CLS_ICON
#define WINDOW_CLS_ICON
Definition: window.h:12
initialize_description_lines
static void initialize_description_lines(screen_t *screen, int y)
Definition: screen_print_preview.c:128
screen_print_preview_init
static void screen_print_preview_init(screen_t *screen)
Definition: screen_print_preview.c:222
MSGBOX_BTN_CUSTOM3
#define MSGBOX_BTN_CUSTOM3
Definition: window_msgbox.h:28
WINDOW_CLS_TEXT
#define WINDOW_CLS_TEXT
Definition: window.h:10
resource_font
font_t * resource_font(uint16_t id)
Definition: guitypes.c:186
WINDOW_EVENT_CLICK
#define WINDOW_EVENT_CLICK
Definition: window.h:46
FR_OK
Definition: ff.h:215
window_create_ptr
int16_t window_create_ptr(int16_t cls_id, int16_t id_parent, rect_ui16_t rect, void *ptr)
Definition: window.c:102
window_enable
void window_enable(int16_t id)
Definition: window.c:517
IDR_FNT_SMALL
#define IDR_FNT_SMALL
Definition: resource.h:9
WINDOW_EVENT_LOOP
#define WINDOW_EVENT_LOOP
Definition: window.h:49
IDR_PNG_menu_icon_print
#define IDR_PNG_menu_icon_print
Definition: resource.h:28
window_draw
void window_draw(int16_t id)
Definition: window.c:277
_window_text_t::font
font_t * font
Definition: window_text.h:19
screen_print_preview_event
static int screen_print_preview_event(screen_t *screen, window_t *window, uint8_t event, void *param)
Definition: screen_print_preview.c:304
gui_defaults
gui_defaults_t gui_defaults
Definition: gui.c:20
description_line_t::value_buffer
char value_buffer[32]
Definition: screen_print_preview.c:19
createSpeedLookupTable.args
args
Definition: createSpeedLookupTable.py:17
fs_disable
void fs_disable()
Definition: filament_sensor.c:97
gcode_file_path
static const char * gcode_file_path
Definition: screen_print_preview.c:53
description_line_t::value
window_text_t value
Definition: screen_print_preview.c:18
IDR_PNG_menu_icon_back
#define IDR_PNG_menu_icon_back
Definition: resource.h:74
fs_did_filament_runout
int fs_did_filament_runout()
Definition: filament_sensor.c:72
LINE_SPACING
#define LINE_SPACING
Definition: screen_print_preview.c:47
FILINFO
Definition: ff.h:197
f_close
FRESULT f_close(FIL *fp)
Definition: ff.c:3801
point_ui16
static point_ui16_t point_ui16(uint16_t x, uint16_t y)
Definition: guitypes.h:154