Skip to content
Merged
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
29 changes: 29 additions & 0 deletions docs/desktop_applications/01_Overview/Introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@


Welcome to **Desktop Applications with Rust & Slint**!
This week, you will learn to create **desktop applications**, using **Rust** for the business logic and **Slint** for the graphical interface.

The course is structured to gradually take you from the fundamentals of Rust, to UI integration, and finally to completing a full project that you will present at the end of the camp.

---

## Course Tutors
- **Precup Cristiana**
- **Robert Dincă**

---

## Course Structure

1. **Rust for Desktop Apps** – Learn Rust fundamentals, data modeling, and local data storage
2. **Building UIs with Slint** – Create interactive desktop interfaces and handle user events
3. **Networking & APIs** – Fetch and display external data in your applications
4. **Final Project** – Build and present a complete desktop application

---

## What is this course about?

This course is about **building real desktop applications** from start to finish.

You will take an idea, turn it into a working app with an interface, and by the end, you’ll have a **complete desktop application** you can run and showcase.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Installing and configuring
---

### Setting Up the Rust Development Environment

Alright, let's get your computer ready to write some Rust code\! The easiest and official way to install Rust is using `rustup`.

1. **Open Your Terminal/Command Prompt:**

- **Linux/macOS:** Open your regular terminal application.
- **Windows:** Open PowerShell or Command Prompt. (If you're using VS Code, its integrated terminal works great\!)

2. **Install `rustup`:**

- **Linux/macOS:** Copy and paste this command into your terminal and press Enter. Follow the on-screen prompts (usually just pressing Enter for default options).
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
- **Windows:**
- Go to the official `rustup` download page: [https://rustup.rs/](https://rustup.rs/)
- Download the appropriate installer for your system (e.g., `rustup-init.exe` for 64-bit Windows).
- Run the installer and follow the instructions. Choose the default installation options.

3. **Configure Your Shell (Important for Linux/macOS):**

- After `rustup` finishes on Linux/macOS, it will often tell you to run a command to add Rust to your system's `PATH`. This is usually:
```bash
source "$HOME/.cargo/env"
```
- Run this command in your _current_ terminal session. To make it permanent, you might need to add it to your shell's configuration file (like `.bashrc`, `.zshrc`, or `.profile`).

4. **Verify Installation:**

- Close and reopen your terminal/command prompt (or run the `source` command).
- Type these commands to check if Rust and Cargo (Rust's build tool, which comes with `rustup`) are installed correctly:
```bash
rustc --version
cargo --version
```
- You should see version numbers printed for both `rustc` (the Rust compiler) and `cargo`. If you do, congratulations, Rust is installed\!

5. **Install VS Code (Recommended IDE):**
- If you don't have it already, download and install Visual Studio Code: [https://code.visualstudio.com/](https://code.visualstudio.com/)
6. **Install the `Rust Analyzer` Extension:** This is crucial for a great Rust development experience in VS Code (code completion, error checking, formatting, etc.). Open VS Code, go to the Extensions view (Ctrl+Shift+X or Cmd+Shift+X), search for "Rust Analyzer", and install it.

7. **Install the `Slint` Extension:** This is recommanded for a better development experience, featuring auto-complition, go-to definition, refactoring, syntax coloration, and a live preview and editing of Slint GUIs.
48 changes: 48 additions & 0 deletions docs/desktop_applications/02_Rust/02_Project-structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: Project Structure
---

**What is Cargo?**

Cargo is Rust's **build system and package manager** which streamlines almost every aspect of your Rust workflow:

- **Project Creation:** `cargo new` quickly sets up a new Rust project with the correct structure.
- **Building:** `cargo build` compiles your code into an executable program.
- **Running:** `cargo run` builds and then executes your program.
- **Testing:** `cargo test` runs your project's tests.

Let's create our classic "Hello, world\!" program using Cargo.

1. **Create a New Project:**
- In your terminal, navigate to a directory where you want to create your project (e.g., your Desktop or a `dev` folder).
- Run this command:
```bash
cargo new hello_rust_app
```
- Cargo will create a new folder named `hello_rust_app` with a basic project structure inside.
2. **Explore the Project Structure:**
- Navigate into the new folder: `cd hello_rust_app`
- Look at the contents:
- `Cargo.toml`: This is the manifest file for your project. It contains metadata about your project (name, version) and lists its dependencies.
- `src/main.rs`: This is where your main Rust code lives.
- `target/`: (Created after you build) This is where compiled executable files go.
3. **Examine `src/main.rs`:**
- Open `src/main.rs` in your VS Code. You'll see:
```rust
fn main() {
println!("Hello, world!");
}
```
- `fn main()`: This is the main function, the entry point of every Rust executable program.
- `println!`: This is a **macro** (indicated by the `!`). It prints text to the console.
4. **Run Your Application:**
- In your terminal (make sure you're inside the `hello_rust_app` folder), run:
```bash
cargo run
```
- **What happens?**
- Cargo first **compiles** your code (you'll see messages like "Compiling hello_rust_app v0.1.0...").
- Then, it **executes** the compiled program.
- You should see: `Hello, world!` printed in your terminal.

Congratulations\! You've just created and run your very first Rust application.
85 changes: 85 additions & 0 deletions docs/desktop_applications/02_Rust/03_Variables-and-data-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
title: Variables and data types
---

Now let's dive into how Rust handles variables and data. This is where you'll see some key differences from languages like JavaScript or Python.

#### **Immutability by Default:**
This is one of Rust's core principles. By default, variables in Rust are **immutable**, meaning once you give them a value, you cannot change that value. This helps prevent unexpected bugs.

* **Declaring an Immutable Variable:**
```rust
fn main() {
let x = 5; // 'x' is immutable. Its value is 5, and it cannot be changed.
println!("The value of x is: {}", x);
// x = 6; // This would cause a compile-time error! Try uncommenting it.
// println!("The value of x is: {}", x);
}
```

* **Making a Variable Mutable:**
If you *do* want to change a variable's value, you must explicitly mark it as `mut` (short for mutable).
```rust
fn main() {
let mut y = 10; // 'y' is mutable. We can change its value.
println!("The initial value of y is: {}", y);
y = 15; // This is allowed because 'y' is mutable.
println!("The new value of y is: {}", y);
}
```
#### **Type Inference vs. Explicit Types:**
Rust is a **statically typed** language, meaning it knows the type of every variable at compile time. However, it's also very smart and can often **infer** the type based on the value you assign. You don't always *have* to write the type.
* **Type Inference (Common):**
```rust
fn main() {
let age = 30; // Rust infers 'age' is an integer (i32 by default)
let pi = 3.14; // Rust infers 'pi' is a floating-point number (f64 by default)
let is_active = true; // Rust infers 'is_active' is a boolean
let initial = 'A'; // Rust infers 'initial' is a character (single quotes)
let greeting = "Hello"; // Rust infers 'greeting' is a string slice (&str)
println!("Age: {}, Pi: {}, Active: {}, Initial: {}, Greeting: {}", age, pi, is_active, initial, greeting);
}
```
* **Explicit Type Annotation (When needed or for clarity):**
You can explicitly tell Rust the type of a variable. This is useful when inference is ambiguous or for better readability.
```rust
fn main() {
let count: i64 = 100_000_000_000; // Explicitly a 64-bit integer
let temperature: f32 = 25.5; // Explicitly a 32-bit float
let message: &str = "Welcome!"; // Explicitly a string slice
println!("Count: {}, Temp: {}, Message: {}", count, temperature, message);
}
```
#### **Common Primitive Data Types:**
Rust has several built-in primitive types:
* **Integers:** `i8`, `i16`, `i32` (default), `i64`, `i128` (signed integers) and `u8`, `u16`, `u32`, `u64`, `u128` (unsigned integers). The number indicates the bits they use. `isize` and `usize` depend on the architecture (e.g., 32-bit or 64-bit).
* **Floating-Point Numbers:** `f32` (single-precision), `f64` (double-precision, default).
* **Booleans:** `bool` (`true` or `false`).
* **Characters:** `char` (single Unicode scalar value, uses single quotes, e.g., `'A'`, `'😊'`).
* **Strings:** We'll learn more about strings later, but for now, know that `&str` (string slice, immutable reference to text) and `String` (growable, owned string) are the main types.

#### **Constants:**

Constants are always immutable and must have their type explicitly annotated. They can be declared in any scope, including global.

```rust
const MAX_POINTS: u32 = 100_000; // Constants are typically named in SCREAMING_SNAKE_CASE
const APP_VERSION: &str = "1.0.0";
fn main() {
println!("Max points: {}", MAX_POINTS);
println!("App version: {}", APP_VERSION);
}
```

#### **Shadowing:**

Rust allows you to declare a *new* variable with the same name as a previous variable. This "shadows" the previous variable, meaning the new variable takes precedence. This is different from `mut`, as you're creating a new variable, not changing an existing one.
```rust
fn main() {
let spaces = " "; // First 'spaces' variable (string slice)
println!("Spaces (initial): '{}'", spaces);
let spaces = spaces.len(); // 'spaces' is now a new variable, holding the length (an integer)
println!("Spaces (length): {}", spaces); // The old 'spaces' is no longer accessible
}
```
Shadowing is useful when you want to transform a variable's value but keep the same name, without needing to make the original variable mutable.
Loading