Compare commits

..

4 commits

4 changed files with 169 additions and 5 deletions

View file

@ -1,6 +1,10 @@
// Libraries // Libraries
slint::include_modules!(); slint::include_modules!();
use slint::{ModelRc, SharedString, VecModel};
use std::io::Result; use std::io::Result;
use std::rc::Rc;
use super::Backend;
// Macros // Macros
macro_rules! map_err { macro_rules! map_err {
@ -11,7 +15,8 @@ macro_rules! map_err {
// Structures // Structures
pub struct App { pub struct App {
app: Prorater, app: Rc<Prorater>,
backend: Rc<Backend>,
} }
// Implementations // Implementations
@ -23,12 +28,28 @@ impl App {
/// ```rs /// ```rs
/// let app = App::new()?; /// let app = App::new()?;
/// ``` /// ```
pub fn new() -> Result<Self> { pub fn new(backend: Rc<Backend>) -> Result<Self> {
// Creating our new app // Creating our new app
let app = map_err!(Prorater::new())?; let app = map_err!(Prorater::new())?;
// Setting the Membership Options
let memberships = {
let vec_model: VecModel<SharedString> = {
let result = VecModel::from(vec![SharedString::from("Select One...")]);
for i in backend.get_memberships() {
result.push(SharedString::from(i));
}
result
};
ModelRc::new(vec_model)
};
app.set_membership_names(memberships.clone());
// Turning the App into an Rc
let app = Rc::new(app);
// Returning Self // Returning Self
Ok(Self { app }) Ok(Self { app, backend })
} }
// Functions // Functions
@ -39,6 +60,20 @@ impl App {
/// app.start()?; /// app.start()?;
/// ``` /// ```
pub fn start(&self) -> Result<()> { pub fn start(&self) -> Result<()> {
// Creating an Rc of our App
let app = Rc::clone(&self.app);
// Setting the on_submit function
self.app.on_on_calculate(move || {
// Getting the prices of the stuff
let current_membership = app.get_current_membership();
let new_membership = app.get_new_membership();
// DEBUG
println!("Current Membership: {}", current_membership);
println!("New Membership: {}", new_membership);
});
// Starting our application // Starting our application
map_err!(self.app.run())?; map_err!(self.app.run())?;

View file

@ -0,0 +1,50 @@
// Libraries
use std::io::Result;
// Structures
pub struct Backend {
memberships: Vec<String>,
}
// Implementations
impl Backend {
// Constructors
/// Creates a new Backend
///
/// # Arguments
/// * `fetch` - Uses the **Internet** to fetch the latest prices for memberships.
///
/// # Examples
/// ```rs
/// let backend = Backend::new(true)?;
/// ```
pub fn new(fetch: bool) -> Result<Self> {
// Did we want to fetch our prices?
let memberships: Vec<String> = if fetch {
// Use Internet to get prices
unimplemented!("TODO: Implement online Membership Price Fetching");
} else {
// Manually creating our prices
vec![
"Super ($41.99)".to_string(),
"Deluxe ($36.99)".to_string(),
"Standard ($31.99)".to_string(),
"Basic ($26.99)".to_string(),
]
};
// Return Self
Ok(Self { memberships })
}
// Functions
/// Gets the list of current memberships
///
/// # Examples
/// ```rs
/// app.set_membership_names(backend.get_memberships());
/// ```
pub fn get_memberships(&self) -> Vec<String> {
self.memberships.clone()
}
}

View file

@ -2,12 +2,17 @@
mod app; mod app;
use app::App; use app::App;
mod backend; mod backend;
use backend::Backend;
use std::io::Result; use std::io::Result;
use std::rc::Rc;
// Entry Point // Entry Point
fn main() -> Result<()> { fn main() -> Result<()> {
// Creating a Backend
let backend = Rc::new(Backend::new(false)?);
// Creating a new App // Creating a new App
let app = App::new()?; let app = App::new(Rc::clone(&backend))?;
// Starting our App // Starting our App
app.start()?; app.start()?;

View file

@ -1,10 +1,15 @@
import { Button, VerticalBox, HorizontalBox } from "std-widgets.slint"; import { DatePickerPopup, Button, VerticalBox, HorizontalBox, ComboBox } from "std-widgets.slint";
export component Prorater inherits Window { export component Prorater inherits Window {
title: "Auto Spa Express - Prorater"; title: "Auto Spa Express - Prorater";
width: 1024px; width: 1024px;
height: 720px; height: 720px;
in property <[string]> membership_names: ["Select One..."];
out property <string> current_membership;
out property <string> new_membership;
callback on_calculate();
VerticalBox { VerticalBox {
Image { Image {
source: @image-url("../data/logo.png"); source: @image-url("../data/logo.png");
@ -17,5 +22,74 @@ export component Prorater inherits Window {
font-size: 4rem; font-size: 4rem;
horizontal-alignment: center; horizontal-alignment: center;
} }
VerticalBox {
HorizontalBox {
VerticalBox {
Text {
text: "Current Membership";
font-size: 1.25rem;
}
current_membership := ComboBox {
model: root.membership_names;
current-index: 0;
selected(current-value) => {
root.current_membership = current-value;
}
}
}
VerticalBox {
Text {
text: "New Membership";
font-size: 1.25rem;
}
new_membership := ComboBox {
model: root.membership_names;
current-index: 0;
selected(current-value) => {
root.new_membership = current-value;
}
}
}
}
}
VerticalBox {
HorizontalBox {
last_billing_date := Button {
text: "Last Billing Date";
clicked => {
date-picker.show();
}
}
}
}
VerticalBox {
Button {
text: "Calculate";
clicked => {
on_calculate();
}
}
}
date_picker := DatePickerPopup {
x: (root.width - self.width) / 2;
y: (root.height - self.height) / 2;
close-policy: PopupClosePolicy.no-auto-close;
accepted(date) => {
date_picker.close();
last-billing-date.text = date.month + "/" + date.day + "/" + date.year;
}
canceled => {
date-picker.close();
}
}
} }
} }