Rework the mobile UIs on native components and fix layout bugs everywhere.

Android moves to Material 3 (navigation bar, app bars, list items,
bottom sheets, pager) with a real back stack. iOS hides the tab bar in
exercises so the bottom action is reachable, aligns content, and uses
system colours so themes and dark mode work. Both pick a readable
accent tint. Desktop keeps the VLSM table inside the window and gives
statistics the same header rhythm as other pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
pepaskopec-blip 2026-09-18 15:37:15 +02:00
commit 0621311b4c
25 changed files with 1965 additions and 1836 deletions

View file

@ -225,6 +225,8 @@ const TrEntry tr_ui[] = {
{"stats", "Statistiky", "Statistics"},
{"stats_title", "Statistiky", "Statistics"},
{"stats_sub", "Přehled vašeho pokroku.", "Overview of your progress."},
{"mluv_sub", "Cvičení z mluvnice – styl maturita / přijímačky z ČJL",
"Grammar exercises in the style of the maturita and entrance exams"},
{"stats_ex_label", "Cvičení", "Exercises"},
{"stats_pct_label", "Hotovo", "Done"},
{"stats_units_label", "Jednotky", "Units"},

View file

@ -61,8 +61,7 @@ void mluvnice_init(void) {
mluv_unit.title = "Mluvnice";
mluv_unit.page = "mluvnice";
mluv_unit.ex_tag = "mluv";
mluv_unit.sub_key = "Cvičení z mluvnice – styl maturita / "
"přijímačky z ČJL";
mluv_unit.sub_key = "mluv_sub";
mluv_unit.back_target = "czechmap";
mluv_unit.progress_file = app_progress_mluvnice;
mluv_unit.n_ex = MLUV_N_EX;

View file

@ -2669,7 +2669,10 @@ GtkWidget *net_qz_make_entry(void) {
GtkWidget *e = gtk_entry_new();
gtk_widget_set_hexpand(e, TRUE);
gtk_editable_set_width_chars(GTK_EDITABLE(e), 15);
/* Four address columns must share the window; 15 chars each pushed the
* last column past the right edge. */
gtk_editable_set_width_chars(GTK_EDITABLE(e), 7);
gtk_editable_set_max_width_chars(GTK_EDITABLE(e), 16);
return e;
}
@ -2688,8 +2691,10 @@ GtkWidget *build_net_exercise_page(void) {
top_bar("netunit1", "net_ex_title", NULL));
scroll = gtk_scrolled_window_new();
/* Never scroll sideways: the address table must shrink to the window
* instead of pushing its last column off screen. */
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand(scroll, TRUE);
gtk_widget_set_margin_top(scroll, 12);
gtk_box_append(GTK_BOX(page), scroll);
@ -2732,6 +2737,7 @@ GtkWidget *build_net_exercise_page(void) {
gtk_grid_set_row_spacing(GTK_GRID(table), 6);
gtk_grid_set_column_spacing(GTK_GRID(table), 8);
gtk_widget_set_margin_top(table, 6);
gtk_widget_set_hexpand(table, TRUE);
gtk_box_append(GTK_BOX(task), table);
for (guint c = 1; c < 6; c++) {

View file

@ -299,9 +299,11 @@ GtkWidget *build_stats_page(void) {
outer = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_add_css_class(outer, "stats-page");
/* Same header rhythm as the other pages (top_bar). */
top = gtk_center_box_new();
gtk_widget_set_margin_top(top, 2);
gtk_widget_set_margin_bottom(top, 6);
gtk_widget_add_css_class(top, "page-top");
gtk_widget_set_margin_top(top, 8);
gtk_widget_set_margin_bottom(top, 18);
gtk_box_append(GTK_BOX(outer), top);
back = make_back_button("subjects");