Skip to content

Commit

Permalink
Merge pull request #74 from Leif-Rydenfalk/main
Browse files Browse the repository at this point in the history
Synth example fix
  • Loading branch information
wtholliday authored Jan 24, 2025
2 parents 4bfe622 + 2dcfd6a commit f4d9e73
Show file tree
Hide file tree
Showing 4 changed files with 532 additions and 373 deletions.
48 changes: 23 additions & 25 deletions examples/calculator/src/calculator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ use rui::*;
/// Represents the state of the clear button functionality.
/// Used to toggle between Clear (C) and All Clear (AC) modes.
#[derive(PartialEq, Clone, Copy)]
enum ClearState {
/// Initial state - displays "C"
Initial,
/// State after clearing - displays "AC"
JustCleared,
enum ClearMode {
/// Initial state - displays "C", only clears current input
OnlyInput,
/// State after clearing - displays "AC", resets all calculator state
FullReset,
}

/// Represents the basic arithmetic operations supported by the calculator.
Expand Down Expand Up @@ -362,7 +362,7 @@ impl Calculator {
},
Button::Special(action) => match action {
SpecialOperator::Clear => {
if cx[s].clear_state == ClearState::JustCleared {
if cx[s].clear_mode == ClearMode::FullReset {
"AC".to_string()
} else {
"C".to_string()
Expand Down Expand Up @@ -404,7 +404,7 @@ pub struct CalculatorState {
/// The last operator used (for repeat calculations)
last_operator: Option<Operator>,
/// Current state of the clear button (C/AC)
clear_state: ClearState,
clear_mode: ClearMode,
}

impl CalculatorState {
Expand All @@ -417,7 +417,7 @@ impl CalculatorState {
has_error: false,
is_result_displayed: false,
last_operator: None,
clear_state: ClearState::Initial,
clear_mode: ClearMode::OnlyInput,
}
}

Expand All @@ -435,13 +435,7 @@ impl CalculatorState {
Some(Operator::Add) => first_operand + second_operand,
Some(Operator::Subtract) => first_operand - second_operand,
Some(Operator::Multiply) => first_operand * second_operand,
Some(Operator::Divide) => {
if second_operand == 0.0 {
self.has_error = true;
return; // Early return on division by zero
}
first_operand / second_operand
}
Some(Operator::Divide) => first_operand / second_operand,
None => return, // Handle the case where no operator is set
};

Expand Down Expand Up @@ -511,7 +505,7 @@ impl CalculatorState {
self.is_input_new = true;
self.has_error = false;
self.is_result_displayed = false;
self.clear_state = ClearState::Initial;
self.clear_mode = ClearMode::OnlyInput;
}

/// Processes button presses and updates calculator state accordingly.
Expand All @@ -523,10 +517,10 @@ impl CalculatorState {
| Button::Special(SpecialOperator::Percentage)
| Button::Special(SpecialOperator::Equals)
| Button::Special(SpecialOperator::Decimal) => {
if self.clear_state == ClearState::JustCleared {
if self.clear_mode == ClearMode::FullReset {
self.reset();
} else {
self.clear_state = ClearState::Initial;
self.clear_mode = ClearMode::OnlyInput;
}

match button {
Expand Down Expand Up @@ -558,16 +552,20 @@ impl CalculatorState {
}
}
Button::Special(SpecialOperator::Clear) => {
if self.second_operand == "0"
&& self.first_operand == "0"
&& self.current_operator.is_none()
if self.second_operand != "0"
|| self.current_operator.is_some()
|| self.is_result_displayed
{
self.reset();
self.clear_state = ClearState::JustCleared;
} else {
// If there's any ongoing state, first clear the current input
self.second_operand = "0".to_string();
self.current_operator = None;
self.is_input_new = true;
self.clear_state = ClearState::Initial;
self.is_result_displayed = false;
self.clear_mode = ClearMode::FullReset;
} else {
// If already cleared, perform a full reset
self.reset();
self.clear_mode = ClearMode::OnlyInput;
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions examples/custom_modifier_with_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ impl Default for MyState {
trait MyMod: View + Sized {
fn my_modifier(self) -> impl View {
state(MyState::default, move |s, cx| {
self.clone().offset(LocalOffset::new(0.0, cx[s].offset))
self.clone()
.offset(LocalOffset::new(0.0, cx[s].offset))
.anim(move |cx, _| {
cx[s].offset *= 0.9;
})
Expand All @@ -33,4 +34,4 @@ fn my_text(name: &str) -> impl View {

fn main() {
hstack((my_text("without"), my_text("with").my_modifier())).run()
}
}
28 changes: 21 additions & 7 deletions examples/synth/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::sync::{Arc, Mutex};
mod midi_keyboard;
mod synth;

use midi_keyboard::{MidiFrequency, MidiNote, MidiNoteId};
use midi_keyboard::{MidiFrequency, MidiKeyboard, MidiNoteId};
use synth::{Oscillator, Synth};

use rui::*;
Expand All @@ -21,18 +21,32 @@ fn main() {
});

// Create and configure the MIDI keyboard
midi_keyboard::MidiKeyboard::new()
MidiKeyboard::new()
.num_keys(25)
.on_note_begin(move |note: MidiNote| {
.start_octave(4)
.max_simultaneous_keys(5)
.on_note_begin(move |event| {
let note = event.note;

let mut synth = synth.lock().unwrap();
let frequency: MidiFrequency = note.try_into().unwrap();

// Get the frequency of the note.
let frequency: MidiFrequency = note.frequency();

// Create an audio source for the note.
let audio_source = Oscillator::sine_wave(frequency).amplify(1.0);
let source_id: MidiNoteId = note.try_into().unwrap();

// Get the note id (u8) if you need it. 0 is the lowest note. 127 is the highest note.
let source_id: MidiNoteId = note.id();

// Send the audio source to the synth.
synth.play_source(Box::new(audio_source), source_id);
})
.on_note_end(move |note: MidiNote| {
.on_note_end(move |event| {
let note = event.note;

let mut synth = synth_clone.lock().unwrap();
let source_id: MidiNoteId = note.try_into().unwrap();
let source_id: MidiNoteId = note.id();
synth.release_source(source_id);
})
.show()
Expand Down
Loading

0 comments on commit f4d9e73

Please sign in to comment.