mirror of
https://github.com/pepaskopec-blip/Graduately.git
synced 2026-10-27 15:14:35 +00:00
First commit, introduction message added
This commit is contained in:
parent
a6546e3502
commit
508be38c3f
4 changed files with 216 additions and 0 deletions
76
CLAUDE.md
Normal file
76
CLAUDE.md
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Development Commands
|
||||||
|
|
||||||
|
- **Build**: Compile the GTK application using the Makefile:
|
||||||
|
```sh
|
||||||
|
make
|
||||||
|
```
|
||||||
|
Or manually with gcc:
|
||||||
|
```sh
|
||||||
|
gcc -o sprechen sprechen.c `pkg-config --cflags --libs gtk4`
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Run**: Execute the built binary:
|
||||||
|
```sh
|
||||||
|
make run
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```sh
|
||||||
|
./sprechen
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Clean**: Remove compiled binaries:
|
||||||
|
```sh
|
||||||
|
make clean
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```sh
|
||||||
|
rm -f sprechen
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Format**: If using clang-format, run:
|
||||||
|
```sh
|
||||||
|
clang-format -i *.c *.h
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Lint**: Use `clang-tidy` or `cppcheck` for static analysis:
|
||||||
|
```sh
|
||||||
|
clang-tidy sprechen.c -- `pkg-config --cflags gtk4`
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```sh
|
||||||
|
cppcheck --enable=all sprechen.c
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Test**: Currently no test framework is integrated. To add unit tests, consider using a lightweight framework like `check` or `cmocka`. Tests can be compiled and run similarly.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
- **Root**: Contains the CLAUDE.md, README.md, .gitignore, LICENSE, Makefile, and source files.
|
||||||
|
- **Source**: The main application resides in a single C file (`sprechen.c`) that uses GTK 4 for the graphical interface.
|
||||||
|
- **Build Artifacts**: Compiled binaries are placed in the project root by default; consider using a `build/` directory for out-of-source builds.
|
||||||
|
- **Dependencies**: Requires GTK 4 development libraries. On macOS, install via Homebrew: `brew install gtk4`. On Linux, use your package manager (e.g., `sudo apt install libgtk-4-dev`).
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
The application is a simple GUI program written in C using GTK 4. It features:
|
||||||
|
- A main window with a title "Sprechen.c".
|
||||||
|
- A vertical box layout containing a centered label with welcome text.
|
||||||
|
- Custom CSS styling for a gradient background and styled label box.
|
||||||
|
- The text size scales dynamically with the window width to ensure readability on different screen sizes.
|
||||||
|
- The GTK application lifecycle is managed via `GtkApplication`, with activation callback setting up the UI.
|
||||||
|
|
||||||
|
Future extensions may include:
|
||||||
|
- Additional widgets for language lessons (buttons, text entry, progress bars).
|
||||||
|
- Separation of UI code into multiple files (e.g., `ui.c`, `ui.h`).
|
||||||
|
- Lesson data structures and loading from external files (JSON or plain text).
|
||||||
|
- Internationalization support using gettext.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Ensure GTK 4 is installed and accessible via pkg-config.
|
||||||
|
- The code adheres to GTK 4 conventions and uses CSS for styling.
|
||||||
|
- When modifying the UI, consider keeping the CSS in a separate file for maintainability, though currently it is embedded for simplicity.
|
||||||
0
error.log
Normal file
0
error.log
Normal file
BIN
sprechen
Executable file
BIN
sprechen
Executable file
Binary file not shown.
140
sprechen.c
Normal file
140
sprechen.c
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GtkWidget *label;
|
||||||
|
GtkCssProvider *provider;
|
||||||
|
} ScaleData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_window_notify (GObject *object,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
// We get the ScaleData from the window
|
||||||
|
ScaleData *scale_data = g_object_get_data(G_OBJECT(object), "scale-data");
|
||||||
|
if (!scale_data || !scale_data->label || !scale_data->provider)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GtkWidget *window = GTK_WIDGET(object);
|
||||||
|
int width;
|
||||||
|
g_object_get(window, "width", &width, NULL);
|
||||||
|
|
||||||
|
// Calculate font size in points based on width
|
||||||
|
// Base: 600px width -> 18 points
|
||||||
|
double points_per_pixel = 18.0 / 600.0;
|
||||||
|
double font_size_points = width * points_per_pixel;
|
||||||
|
// Clamp between 10 and 24 points
|
||||||
|
if (font_size_points < 10.0) font_size_points = 10.0;
|
||||||
|
if (font_size_points > 24.0) font_size_points = 24.0;
|
||||||
|
|
||||||
|
// Update the CSS provider with the new font size
|
||||||
|
char *css_data = g_strdup_printf(
|
||||||
|
"window {"
|
||||||
|
" background-color: #2E3440;"
|
||||||
|
" background-image: linear-gradient(135deg, #2E3440 0%%, #3B4252 100%%);"
|
||||||
|
" color: #ECEFF4;"
|
||||||
|
" font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;"
|
||||||
|
"}"
|
||||||
|
"label {"
|
||||||
|
" margin: 30px;"
|
||||||
|
" padding: 30px;"
|
||||||
|
" background-color: rgba(59, 66, 82, 0.8);"
|
||||||
|
" border-radius: 16px;"
|
||||||
|
" box-shadow: 0 8px 16px rgba(0,0,0,0.4);"
|
||||||
|
" font-size: %dpt;"
|
||||||
|
"}",
|
||||||
|
(int)font_size_points);
|
||||||
|
|
||||||
|
gtk_css_provider_load_from_string(scale_data->provider, css_data);
|
||||||
|
g_free(css_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate(GtkApplication *app, gpointer user_data) {
|
||||||
|
GtkWidget *window;
|
||||||
|
GtkWidget *box;
|
||||||
|
GtkWidget *label;
|
||||||
|
GtkCssProvider *provider;
|
||||||
|
ScaleData *scale_data;
|
||||||
|
|
||||||
|
// Create a new application window
|
||||||
|
window = gtk_application_window_new(app);
|
||||||
|
gtk_window_set_title(GTK_WINDOW(window), "Sprechen.c");
|
||||||
|
gtk_window_set_default_size(GTK_WINDOW(window), 600, 400);
|
||||||
|
|
||||||
|
// Create a vertical box to hold contents
|
||||||
|
box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 20);
|
||||||
|
gtk_widget_set_halign(box, GTK_ALIGN_CENTER);
|
||||||
|
gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
|
||||||
|
gtk_window_set_child(GTK_WINDOW(window), box);
|
||||||
|
|
||||||
|
// Create a label with welcome message
|
||||||
|
label = gtk_label_new("Vítejte ve Sprechen.C!\n\nSprechen.C je vzdělávací program na procvičování Němčiny, určený pro studenty středních škol a gymnázií. Program je napsaný v Céčku studentama ze SSŠVT!");
|
||||||
|
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
|
||||||
|
gtk_label_set_lines(label, -1); // Allow multiple lines
|
||||||
|
gtk_label_set_xalign(label, 0.5); // Center horizontally
|
||||||
|
gtk_label_set_yalign(label, 0.5); // Center vertically
|
||||||
|
gtk_label_set_wrap(label, TRUE); // Enable line wrapping
|
||||||
|
gtk_label_set_max_width_chars(label, 40);
|
||||||
|
gtk_box_append(GTK_BOX(box), label);
|
||||||
|
|
||||||
|
// Create and load CSS for beautiful background with initial font size
|
||||||
|
provider = gtk_css_provider_new();
|
||||||
|
int initial_width = 600; // default width
|
||||||
|
double points_per_pixel = 18.0 / 600.0;
|
||||||
|
double initial_font_size_points = initial_width * points_per_pixel;
|
||||||
|
if (initial_font_size_points < 10.0) initial_font_size_points = 10.0;
|
||||||
|
if (initial_font_size_points > 24.0) initial_font_size_points = 24.0;
|
||||||
|
char *initial_css = g_strdup_printf(
|
||||||
|
"window {"
|
||||||
|
" background-color: #2E3440;"
|
||||||
|
" background-image: linear-gradient(135deg, #2E3440 0%%, #3B4252 100%%);"
|
||||||
|
" color: #ECEFF4;"
|
||||||
|
" font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;"
|
||||||
|
"}"
|
||||||
|
"label {"
|
||||||
|
" margin: 30px;"
|
||||||
|
" padding: 30px;"
|
||||||
|
" background-color: rgba(59, 66, 82, 0.8);"
|
||||||
|
" border-radius: 16px;"
|
||||||
|
" box-shadow: 0 8px 16px rgba(0,0,0,0.4);"
|
||||||
|
" font-size: %dpt;"
|
||||||
|
"}",
|
||||||
|
(int)initial_font_size_points);
|
||||||
|
gtk_css_provider_load_from_string(provider, initial_css);
|
||||||
|
g_free(initial_css);
|
||||||
|
|
||||||
|
// Apply CSS to the window
|
||||||
|
gtk_style_context_add_provider_for_display(
|
||||||
|
gdk_display_get_default(),
|
||||||
|
GTK_STYLE_PROVIDER(provider),
|
||||||
|
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||||
|
|
||||||
|
// We keep the provider to update it later, so we don't unreference it yet
|
||||||
|
// g_object_unref(provider); // We will unreference it in the cleanup? We'll store it in ScaleData and unreference when the window is destroyed.
|
||||||
|
|
||||||
|
// Set up scaling data
|
||||||
|
scale_data = g_new(ScaleData, 1);
|
||||||
|
scale_data->label = label;
|
||||||
|
scale_data->provider = provider;
|
||||||
|
g_object_set_data_full(G_OBJECT(window), "scale-data", scale_data, g_free);
|
||||||
|
|
||||||
|
// Connect to the window's notify::width and notify::height signals
|
||||||
|
g_signal_connect(window, "notify::width", G_CALLBACK(on_window_notify), NULL);
|
||||||
|
g_signal_connect(window, "notify::height", G_CALLBACK(on_window_notify), NULL);
|
||||||
|
|
||||||
|
gtk_window_present(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
GtkApplication *app;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
app = gtk_application_new("org.example.Sprechen", G_APPLICATION_DEFAULT_FLAGS);
|
||||||
|
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
|
||||||
|
status = g_application_run(G_APPLICATION(app), argc, argv);
|
||||||
|
g_object_unref(app);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue