Group the existing hardware lessons under year 1 and lock later years.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
pepaskopec-blip 2026-09-25 21:32:40 +02:00
commit 9e072cb8ae
14 changed files with 191 additions and 17 deletions

105
src/hw.c
View file

@ -324,6 +324,109 @@ void hw_add_node(GtkFixed *fixed, int index) {
gtk_fixed_put(fixed, name, 0, 0);
}
static GtkWidget *hw_year_button(int year, gboolean locked) {
static const char *year_keys[] = {
"hw_year1", "hw_year2", "hw_year3", "hw_year4",
};
GtkWidget *btn;
GtkWidget *row;
GtkWidget *num;
GtkWidget *texts;
GtkWidget *title;
char *num_text;
btn = gtk_button_new();
gtk_widget_add_css_class(btn, "unit-node");
gtk_widget_set_can_focus(btn, FALSE);
gtk_widget_set_hexpand(btn, TRUE);
gtk_widget_set_size_request(btn, -1, 72);
gtk_widget_set_sensitive(btn, !locked);
if (locked)
gtk_widget_add_css_class(btn, "locked");
else
gtk_widget_add_css_class(btn, "current");
row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 14);
gtk_widget_set_halign(row, GTK_ALIGN_START);
gtk_widget_set_valign(row, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start(row, 18);
gtk_widget_set_margin_end(row, 18);
gtk_button_set_child(GTK_BUTTON(btn), row);
num_text = g_strdup_printf("%d", year);
num = gtk_label_new(num_text);
g_free(num_text);
gtk_widget_add_css_class(num, "unit-number");
gtk_widget_set_valign(num, GTK_ALIGN_CENTER);
gtk_box_append(GTK_BOX(row), num);
texts = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
gtk_widget_set_halign(texts, GTK_ALIGN_START);
gtk_widget_set_hexpand(texts, TRUE);
gtk_box_append(GTK_BOX(row), texts);
title = gtk_label_new(NULL);
i18n_bind(title, year_keys[year - 1], 0);
gtk_widget_set_halign(title, GTK_ALIGN_START);
gtk_widget_add_css_class(title, "unit-name");
gtk_box_append(GTK_BOX(texts), title);
if (locked) {
GtkWidget *sub = gtk_label_new(NULL);
GtkWidget *icon = icon_area_new(draw_lock_icon, 0.3451, 0.3569,
0.4392, 18);
i18n_bind(sub, "hw_year_locked_sub", 0);
gtk_widget_set_halign(sub, GTK_ALIGN_START);
gtk_widget_add_css_class(sub, "unit-name-locked");
gtk_box_append(GTK_BOX(texts), sub);
gtk_widget_set_valign(icon, GTK_ALIGN_CENTER);
gtk_box_append(GTK_BOX(row), icon);
} else {
g_object_set_data_full(G_OBJECT(btn), "target",
g_strdup("hwmap"), g_free);
g_signal_connect(btn, "clicked", G_CALLBACK(on_nav_clicked), NULL);
}
return btn;
}
GtkWidget *build_hwyears_page(void) {
GtkWidget *page;
GtkWidget *scroll;
GtkWidget *list;
int y;
page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_hexpand(page, TRUE);
gtk_widget_set_vexpand(page, TRUE);
gtk_widget_set_margin_start(page, 32);
gtk_widget_set_margin_end(page, 32);
gtk_widget_set_margin_top(page, 24);
gtk_widget_set_margin_bottom(page, 24);
gtk_box_append(GTK_BOX(page),
top_bar("subjects", "Technické vybavení", "hw_years_sub"));
scroll = gtk_scrolled_window_new();
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand(scroll, TRUE);
gtk_widget_set_margin_top(scroll, 18);
gtk_box_append(GTK_BOX(page), scroll);
list = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
gtk_widget_set_halign(list, GTK_ALIGN_CENTER);
gtk_widget_set_valign(list, GTK_ALIGN_CENTER);
gtk_widget_set_size_request(list, 360, -1);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll), list);
for (y = 1; y <= 4; y++)
gtk_box_append(GTK_BOX(list), hw_year_button(y, y > 1));
return page;
}
GtkWidget *build_hwmap_page(void) {
GtkWidget *page;
GtkWidget *scroll;
@ -344,7 +447,7 @@ GtkWidget *build_hwmap_page(void) {
gtk_widget_set_margin_bottom(page, 24);
gtk_box_append(GTK_BOX(page),
top_bar("subjects", "Technické vybavení", "hw_sub"));
top_bar("hwyears", "hw_year1", "hw_sub"));
scroll = gtk_scrolled_window_new();
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),

View file

@ -521,6 +521,13 @@ const TrEntry tr_ui[] = {
"This assignment does not fit into a /24 network — tap “Show solution” to see why."},
{"hw_sub", "Vyberte lekci na cestě a začněte procvičovat.",
"Pick a unit on the path and start practicing."},
{"hw_years_sub", "Vyberte ročník a začněte procvičovat.",
"Pick a school year and start practicing."},
{"hw_year1", "1. ročník", "Year 1"},
{"hw_year2", "2. ročník", "Year 2"},
{"hw_year3", "3. ročník", "Year 3"},
{"hw_year4", "4. ročník", "Year 4"},
{"hw_year_locked_sub", "Zatím bez obsahu", "No content yet"},
{"hw_unit1", "Architektura počítače", "Computer architecture"},
{"hw_unit1_sub", "3 snímky o Von Neumannovi a schématu a pak kvíz.",
"3 slides about von Neumann and the model, then a quiz."},

View file

@ -385,7 +385,7 @@ static gboolean shot_later(gpointer data) {
static gboolean run_smoke_test(gpointer data) {
static const char *pages[] = {
"welcome", "subjects", "roadmap", "stats",
"netyears", "netmap", "hwmap", "czechmap",
"netyears", "netmap", "hwyears", "hwmap", "czechmap",
"mluvnice", "readinglist",
"cetba1984", "cetba1984quiz", "cetba1984dej",
"cetbaFuks", "cetbaFuksQuiz", "cetbaFuksDej",
@ -504,6 +504,7 @@ void activate(GtkApplication *app, gpointer user_data) {
gtk_stack_add_named(main_stack, build_stats_page(), "stats");
gtk_stack_add_named(main_stack, build_netyears_page(), "netyears");
gtk_stack_add_named(main_stack, build_netmap_page(), "netmap");
gtk_stack_add_named(main_stack, build_hwyears_page(), "hwyears");
gtk_stack_add_named(main_stack, build_hwmap_page(), "hwmap");
gtk_stack_add_named(main_stack, build_czechmap_page(), "czechmap");
gtk_stack_add_named(main_stack, build_mluvnice_page(), "mluvnice");

View file

@ -843,6 +843,7 @@ void progress_for_hw(ProgressSum *out);
void hw_rail_theme_reset(void);
void czech_rail_theme_reset(void);
void hw_lessons_apply_lang(void);
GtkWidget *build_hwyears_page(void);
GtkWidget *build_hwmap_page(void);
GtkWidget *build_czechmap_page(void);
void mluvnice_init(void);

View file

@ -31,7 +31,7 @@ static const char *subject_page(int i) {
if (i == NET_SUBJ)
return "netyears";
if (i == HW_SUBJ)
return "hwmap";
return "hwyears";
if (i == CZ_SUBJ)
return "czechmap";
return "subjects";
@ -187,6 +187,10 @@ static void catalog_rebuild(void) {
catalog_add(tr(key), tr("search_exercise"), page, FALSE, 3, "kviz quiz");
}
catalog_add_key("hw_year1", "search_lesson", "hwmap", FALSE, 1, "rocnik");
catalog_add_key("hw_year2", "search_lesson", "hwyears", TRUE, 1, "rocnik");
catalog_add_key("hw_year3", "search_lesson", "hwyears", TRUE, 1, "rocnik");
catalog_add_key("hw_year4", "search_lesson", "hwyears", TRUE, 1, "rocnik");
for (i = 1; i <= HW_LESSONS; i++) {
g_snprintf(key, sizeof(key), "hw_unit%d", i);
g_snprintf(page, sizeof(page), "hwunit%d", i);

View file

@ -184,7 +184,7 @@ static const char *subject_target(int i) {
if (i == NET_SUBJ)
return "netyears";
if (i == HW_SUBJ)
return "hwmap";
return "hwyears";
if (i == CZ_SUBJ)
return "czechmap";
return NULL;