wip: almost there
This commit is contained in:
1 parent
f07e345eb2
commit
047c810507
11 files changed
+155
-385
No files matched your search
@@ -1,14 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let g = dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory| {
|
|
||||||
use dioxus_elements::{GlobalAttributes, SvgAttributes};
|
|
||||||
__cx.element(
|
|
||||||
dioxus_elements::button,
|
|
||||||
[dioxus::events::on::onclick(__cx, move |_| {})],
|
|
||||||
[],
|
|
||||||
[],
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
+15
-21
@@ -12,7 +12,7 @@ fn main() {
|
|||||||
|
|
||||||
const APP: FC<()> = |cx, _| {
|
const APP: FC<()> = |cx, _| {
|
||||||
let cur_val = use_state(cx, || 0.0_f64);
|
let cur_val = use_state(cx, || 0.0_f64);
|
||||||
let operator = use_state(cx, || None);
|
let operator = use_state(cx, || None as Option<&'static str>);
|
||||||
let display_value = use_state(cx, || String::from(""));
|
let display_value = use_state(cx, || String::from(""));
|
||||||
|
|
||||||
let clear_display = display_value == "0";
|
let clear_display = display_value == "0";
|
||||||
@@ -25,11 +25,12 @@ const APP: FC<()> = |cx, _| {
|
|||||||
let perform_operation = move || {
|
let perform_operation = move || {
|
||||||
if let Some(op) = operator.as_ref() {
|
if let Some(op) = operator.as_ref() {
|
||||||
let rhs = display_value.parse::<f64>().unwrap();
|
let rhs = display_value.parse::<f64>().unwrap();
|
||||||
let new_val = match op {
|
let new_val = match *op {
|
||||||
Operator::Add => *cur_val + rhs,
|
"+" => *cur_val + rhs,
|
||||||
Operator::Sub => *cur_val - rhs,
|
"-" => *cur_val - rhs,
|
||||||
Operator::Mul => *cur_val * rhs,
|
"*" => *cur_val * rhs,
|
||||||
Operator::Div => *cur_val / rhs,
|
"/" => *cur_val / rhs,
|
||||||
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
cur_val.set(new_val);
|
cur_val.set(new_val);
|
||||||
display_value.set(new_val.to_string());
|
display_value.set(new_val.to_string());
|
||||||
@@ -56,10 +57,10 @@ const APP: FC<()> = |cx, _| {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let keydownhandler = move |evt: KeyboardEvent| match evt.key_code() {
|
let keydownhandler = move |evt: KeyboardEvent| match evt.key_code() {
|
||||||
KeyCode::Add => operator.set(Some(Operator::Add)),
|
KeyCode::Add => operator.set(Some("+")),
|
||||||
KeyCode::Subtract => operator.set(Some(Operator::Sub)),
|
KeyCode::Subtract => operator.set(Some("-")),
|
||||||
KeyCode::Divide => operator.set(Some(Operator::Div)),
|
KeyCode::Divide => operator.set(Some("/")),
|
||||||
KeyCode::Multiply => operator.set(Some(Operator::Mul)),
|
KeyCode::Multiply => operator.set(Some("*")),
|
||||||
KeyCode::Num0 => input_digit(0),
|
KeyCode::Num0 => input_digit(0),
|
||||||
KeyCode::Num1 => input_digit(1),
|
KeyCode::Num1 => input_digit(1),
|
||||||
KeyCode::Num2 => input_digit(2),
|
KeyCode::Num2 => input_digit(2),
|
||||||
@@ -99,23 +100,16 @@ const APP: FC<()> = |cx, _| {
|
|||||||
})}
|
})}
|
||||||
}
|
}
|
||||||
div { class: "operator-keys"
|
div { class: "operator-keys"
|
||||||
CalculatorKey { name: "key-divide", onclick: move |_| operator.set(Some(Operator::Div)) "÷" }
|
CalculatorKey { name: "key-divide", onclick: move |_| operator.set(Some("/")) "÷" }
|
||||||
CalculatorKey { name: "key-multiply", onclick: move |_| operator.set(Some(Operator::Mul)) "×" }
|
CalculatorKey { name: "key-multiply", onclick: move |_| operator.set(Some("*")) "×" }
|
||||||
CalculatorKey { name: "key-subtract", onclick: move |_| operator.set(Some(Operator::Sub)) "−" }
|
CalculatorKey { name: "key-subtract", onclick: move |_| operator.set(Some("-")) "−" }
|
||||||
CalculatorKey { name: "key-add", onclick: move |_| operator.set(Some(Operator::Add)) "+" }
|
CalculatorKey { name: "key-add", onclick: move |_| operator.set(Some("+")) "+" }
|
||||||
CalculatorKey { name: "key-equals", onclick: move |_| perform_operation() "=" }
|
CalculatorKey { name: "key-equals", onclick: move |_| perform_operation() "=" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Operator {
|
|
||||||
Add,
|
|
||||||
Sub,
|
|
||||||
Mul,
|
|
||||||
Div,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Props)]
|
#[derive(Props)]
|
||||||
struct CalculatorKeyProps<'a> {
|
struct CalculatorKeyProps<'a> {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
|
|||||||
+59
-32
@@ -6,7 +6,6 @@ use dioxus::prelude::*;
|
|||||||
fn main() {
|
fn main() {
|
||||||
dioxus::web::launch(App, |c| c);
|
dioxus::web::launch(App, |c| c);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Scene {
|
enum Scene {
|
||||||
ClientsList,
|
ClientsList,
|
||||||
NewClientForm,
|
NewClientForm,
|
||||||
@@ -28,50 +27,78 @@ static App: FC<()> = |cx, _| {
|
|||||||
let lastname = use_state(cx, || String::new());
|
let lastname = use_state(cx, || String::new());
|
||||||
let description = use_state(cx, || String::new());
|
let description = use_state(cx, || String::new());
|
||||||
|
|
||||||
match *scene {
|
let scene = match *scene {
|
||||||
Scene::ClientsList => {
|
Scene::ClientsList => {
|
||||||
rsx!(cx, div { class: "crm"
|
rsx!(cx, div { class: "crm"
|
||||||
h1 { "List of clients" }
|
h2 { "List of clients" margin_bottom: "10px" }
|
||||||
div { class: "clients" {clients.read().iter().map(|client| rsx!(
|
div { class: "clients" margin_left: "10px"
|
||||||
div { class: "client" style: "margin-bottom: 50px"
|
{clients.read().iter().map(|client| rsx!(
|
||||||
p { "First Name: {client.first_name}" }
|
div { class: "client" style: "margin-bottom: 50px"
|
||||||
p { "Last Name: {client.last_name}" }
|
p { "First Name: {client.first_name}" }
|
||||||
p {"Description: {client.description}"}
|
p { "Last Name: {client.last_name}" }
|
||||||
}))}
|
p {"Description: {client.description}"}
|
||||||
|
})
|
||||||
|
)}
|
||||||
}
|
}
|
||||||
button { onclick: move |_| scene.set(Scene::NewClientForm), "Add New" }
|
button { class: "pure-button pure-button-primary" onclick: move |_| scene.set(Scene::NewClientForm), "Add New" }
|
||||||
button { onclick: move |_| scene.set(Scene::Settings), "Settings" }
|
button { class: "pure-button" onclick: move |_| scene.set(Scene::Settings), "Settings" }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Scene::NewClientForm => {
|
Scene::NewClientForm => {
|
||||||
rsx!(cx, div { class: "crm"
|
let add_new = move |_| {
|
||||||
h1 {"Add new client"}
|
clients.write().push(Client {
|
||||||
div { class: "names"
|
|
||||||
input { class: "new-client firstname" placeholder: "First name"
|
|
||||||
onchange: move |e| firstname.set(e.value())
|
|
||||||
}
|
|
||||||
input { class: "new-client lastname" placeholder: "Last name"
|
|
||||||
onchange: move |e| lastname.set(e.value())
|
|
||||||
}
|
|
||||||
textarea { class: "new-client description" placeholder: "Description"
|
|
||||||
onchange: move |e| description.set(e.value())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
button { disabled: "false", onclick: move |_| clients.write().push(Client {
|
|
||||||
description: (*description).clone(),
|
description: (*description).clone(),
|
||||||
first_name: (*firstname).clone(),
|
first_name: (*firstname).clone(),
|
||||||
last_name: (*lastname).clone(),
|
last_name: (*lastname).clone(),
|
||||||
|
});
|
||||||
}), "Add New" }
|
description.set(String::new());
|
||||||
button { onclick: move |_| scene.set(Scene::ClientsList), "Go Back" }
|
firstname.set(String::new());
|
||||||
|
lastname.set(String::new());
|
||||||
|
};
|
||||||
|
rsx!(cx, div { class: "crm"
|
||||||
|
h2 {"Add new client" margin_bottom: "10px" }
|
||||||
|
form { class: "pure-form"
|
||||||
|
input { class: "new-client firstname" placeholder: "First name" value: "{firstname}"
|
||||||
|
oninput: move |e| firstname.set(e.value())
|
||||||
|
}
|
||||||
|
input { class: "new-client lastname" placeholder: "Last name" value: "{lastname}"
|
||||||
|
oninput: move |e| lastname.set(e.value())
|
||||||
|
}
|
||||||
|
textarea { class: "new-client description" placeholder: "Description" value: "{description}"
|
||||||
|
oninput: move |e| description.set(e.value())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button { class: "pure-button pure-button-primary", onclick: {add_new}, "Add New" }
|
||||||
|
button { class: "pure-button", onclick: move |_| scene.set(Scene::ClientsList), "Go Back" }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Scene::Settings => {
|
Scene::Settings => {
|
||||||
rsx!(cx, div {
|
rsx!(cx, div {
|
||||||
h1 {"Settings"}
|
h2 {"Settings" margin_bottom: "10px" }
|
||||||
button { onclick: move |_| clients.write().clear() "Remove all clients" }
|
button {
|
||||||
button { onclick: move |_| scene.set(Scene::ClientsList), "Go Back" }
|
background: "rgb(202, 60, 60)"
|
||||||
|
class: "pure-button pure-button-primary"
|
||||||
|
onclick: move |_| clients.write().clear(),
|
||||||
|
"Remove all clients"
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
class: "pure-button pure-button-primary"
|
||||||
|
onclick: move |_| scene.set(Scene::ClientsList),
|
||||||
|
"Go Back"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
rsx!(cx, body {
|
||||||
|
link {
|
||||||
|
rel: "stylesheet"
|
||||||
|
href: "https://unpkg.com/purecss@2.0.6/build/pure-min.css"
|
||||||
|
integrity: "sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5"
|
||||||
|
crossorigin: "anonymous"
|
||||||
|
}
|
||||||
|
margin_left: "35%"
|
||||||
|
h1 {"Dioxus CRM Example"}
|
||||||
|
{scene}
|
||||||
|
})
|
||||||
};
|
};
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
use dioxus::desktop::wry::application::dpi::LogicalSize;
|
use dioxus::desktop::wry::application::dpi::LogicalSize;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use std::fs::{self, DirEntry};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
@@ -73,7 +72,7 @@ impl Files {
|
|||||||
|
|
||||||
fn reload_path_list(&mut self) {
|
fn reload_path_list(&mut self) {
|
||||||
let cur_path = self.path_stack.last().unwrap();
|
let cur_path = self.path_stack.last().unwrap();
|
||||||
let paths = match fs::read_dir(cur_path) {
|
let paths = match std::fs::read_dir(cur_path) {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err = format!("An error occured: {:?}", err);
|
let err = format!("An error occured: {:?}", err);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ fn main() {
|
|||||||
// .. should result in an "invalid node tree"
|
// .. should result in an "invalid node tree"
|
||||||
let edits = vec![
|
let edits = vec![
|
||||||
CreateElement { tag: "div", id: 0 },
|
CreateElement { tag: "div", id: 0 },
|
||||||
// CreatePlaceholder { id: 1 },
|
|
||||||
CreateElement { tag: "h1", id: 2 },
|
CreateElement { tag: "h1", id: 2 },
|
||||||
CreateTextNode {
|
CreateTextNode {
|
||||||
text: "hello world",
|
text: "hello world",
|
||||||
@@ -15,7 +14,6 @@ fn main() {
|
|||||||
AppendChildren { many: 1 },
|
AppendChildren { many: 1 },
|
||||||
AppendChildren { many: 1 },
|
AppendChildren { many: 1 },
|
||||||
AppendChildren { many: 1 },
|
AppendChildren { many: 1 },
|
||||||
// ReplaceWith { many: 1 },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
dioxus_desktop::WebviewRenderer::run_with_edits(App, (), |c| c, Some(edits)).expect("failed");
|
dioxus_desktop::WebviewRenderer::run_with_edits(App, (), |c| c, Some(edits)).expect("failed");
|
||||||
|
|||||||
+26
-29
@@ -33,40 +33,38 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static App: FC<()> = |cx, props| {
|
static App: FC<()> = |cx, props| {
|
||||||
let state = use_state(cx, || Calculator::new());
|
let state = use_ref(cx, || Calculator::new());
|
||||||
|
|
||||||
let clear_display = state.display_value.eq("0");
|
let clear_display = state.read().display_value.eq("0");
|
||||||
let clear_text = if clear_display { "C" } else { "AC" };
|
let clear_text = if clear_display { "C" } else { "AC" };
|
||||||
let formatted = state.formatted_display();
|
let formatted = state.read().formatted_display();
|
||||||
|
|
||||||
cx.render(rsx! {
|
rsx!(cx, div { id: "wrapper"
|
||||||
div { id: "wrapper"
|
div { class: "app", style { "{STYLE}" }
|
||||||
div { class: "app", style { "{STYLE}" }
|
div { class: "calculator", onkeypress: move |evt| state.write().handle_keydown(evt),
|
||||||
div { class: "calculator", onkeypress: move |evt| state.modify().handle_keydown(evt),
|
div { class: "calculator-display", "{formatted}"}
|
||||||
div { class: "calculator-display", "{formatted}"}
|
div { class: "calculator-keypad"
|
||||||
div { class: "calculator-keypad"
|
div { class: "input-keys"
|
||||||
div { class: "input-keys"
|
div { class: "function-keys"
|
||||||
div { class: "function-keys"
|
CalculatorKey { name: "key-clear", onclick: move |_| state.write().clear_display(), "{clear_text}" }
|
||||||
CalculatorKey { name: "key-clear", onclick: move |_| state.modify().clear_display(), "{clear_text}" }
|
CalculatorKey { name: "key-sign", onclick: move |_| state.write().toggle_sign(), "±"}
|
||||||
CalculatorKey { name: "key-sign", onclick: move |_| state.modify().toggle_sign(), "±"}
|
CalculatorKey { name: "key-percent", onclick: move |_| state.write().toggle_percent(), "%"}
|
||||||
CalculatorKey { name: "key-percent", onclick: move |_| state.modify().toggle_percent(), "%"}
|
|
||||||
}
|
|
||||||
div { class: "digit-keys"
|
|
||||||
CalculatorKey { name: "key-0", onclick: move |_| state.modify().input_digit(0), "0" }
|
|
||||||
CalculatorKey { name: "key-dot", onclick: move |_| state.modify().input_dot(), "●" }
|
|
||||||
{(1..10).map(move |k| rsx!{
|
|
||||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.modify().input_digit(k), "{k}" }
|
|
||||||
})}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
div { class: "operator-keys"
|
div { class: "digit-keys"
|
||||||
CalculatorKey { name:"key-divide", onclick: move |_| state.modify().set_operator(Operator::Div), "÷" }
|
CalculatorKey { name: "key-0", onclick: move |_| state.write().input_digit(0), "0" }
|
||||||
CalculatorKey { name:"key-multiply", onclick: move |_| state.modify().set_operator(Operator::Mul), "×" }
|
CalculatorKey { name: "key-dot", onclick: move |_| state.write().input_dot(), "●" }
|
||||||
CalculatorKey { name:"key-subtract", onclick: move |_| state.modify().set_operator(Operator::Sub), "−" }
|
{(1..10).map(move |k| rsx!{
|
||||||
CalculatorKey { name:"key-add", onclick: move |_| state.modify().set_operator(Operator::Add), "+" }
|
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.write().input_digit(k), "{k}" }
|
||||||
CalculatorKey { name:"key-equals", onclick: move |_| state.modify().perform_operation(), "=" }
|
})}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
div { class: "operator-keys"
|
||||||
|
CalculatorKey { name:"key-divide", onclick: move |_| state.write().set_operator(Operator::Div), "÷" }
|
||||||
|
CalculatorKey { name:"key-multiply", onclick: move |_| state.write().set_operator(Operator::Mul), "×" }
|
||||||
|
CalculatorKey { name:"key-subtract", onclick: move |_| state.write().set_operator(Operator::Sub), "−" }
|
||||||
|
CalculatorKey { name:"key-add", onclick: move |_| state.write().set_operator(Operator::Add), "+" }
|
||||||
|
CalculatorKey { name:"key-equals", onclick: move |_| state.write().perform_operation(), "=" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +87,6 @@ fn CalculatorKey<'a, 'r>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomT
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Calculator {
|
struct Calculator {
|
||||||
display_value: String,
|
display_value: String,
|
||||||
operator: Option<Operator>,
|
operator: Option<Operator>,
|
||||||
|
|||||||
+11
-13
@@ -11,23 +11,21 @@ fn main() {
|
|||||||
dioxus::desktop::launch(App, |c| c);
|
dioxus::desktop::launch(App, |c| c);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static App: FC<()> = |cx, props| {
|
pub static App: FC<()> = |cx, _| {
|
||||||
let state = use_state(cx, PlayerState::new);
|
let state = use_state(cx, PlayerState::new);
|
||||||
|
|
||||||
let is_playing = state.is_playing();
|
let is_playing = state.is_playing();
|
||||||
|
|
||||||
cx.render(rsx! {
|
rsx!(cx, div {
|
||||||
div {
|
h1 {"Select an option"}
|
||||||
h1 {"Select an option"}
|
h3 {"The radio is... {is_playing}!"}
|
||||||
h3 {"The radio is... {is_playing}!"}
|
button {
|
||||||
button {
|
"Pause"
|
||||||
"Pause"
|
onclick: move |_| state.modify().reduce(PlayerAction::Pause)
|
||||||
onclick: move |_| state.modify().reduce(PlayerAction::Pause)
|
}
|
||||||
}
|
button {
|
||||||
button {
|
"Play"
|
||||||
"Play"
|
onclick: move |_| state.modify().reduce(PlayerAction::Play)
|
||||||
onclick: move |_| state.modify().reduce(PlayerAction::Play)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
//! Example: Webview Renderer
|
|
||||||
//! -------------------------
|
|
||||||
//!
|
|
||||||
//! This example shows how to use the dioxus_desktop crate to build a basic desktop application.
|
|
||||||
//!
|
|
||||||
//! Under the hood, the dioxus_desktop crate bridges a native Dioxus VirtualDom with a custom prebuit application running
|
|
||||||
//! in the webview runtime. Custom handlers are provided for the webview instance to consume patches and emit user events
|
|
||||||
//! into the native VDom instance.
|
|
||||||
//!
|
|
||||||
//! Currently, NodeRefs won't work properly, but all other event functionality will.
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
dioxus::desktop::launch(App, |c| c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static App: FC<()> = |cx, props| {
|
|
||||||
let slides = use_state(cx, SlideController::new);
|
|
||||||
|
|
||||||
let slide = match slides.slide_id {
|
|
||||||
0 => cx.render(rsx!(Title {})),
|
|
||||||
1 => cx.render(rsx!(Slide1 {})),
|
|
||||||
2 => cx.render(rsx!(Slide2 {})),
|
|
||||||
3 => cx.render(rsx!(Slide3 {})),
|
|
||||||
_ => cx.render(rsx!(End {})),
|
|
||||||
};
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
style: {
|
|
||||||
background_color: "red"
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
div { h1 {"my awesome slideshow"} }
|
|
||||||
div {
|
|
||||||
button {"<-", onclick: move |_| slides.modify().go_forward()}
|
|
||||||
h3 { "{slides.slide_id}" }
|
|
||||||
button {"->" onclick: move |_| slides.modify().go_backward()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{slide}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct SlideController {
|
|
||||||
slide_id: isize,
|
|
||||||
}
|
|
||||||
impl SlideController {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self { slide_id: 0 }
|
|
||||||
}
|
|
||||||
fn can_go_forward(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
fn can_go_backward(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
fn go_forward(&mut self) {
|
|
||||||
if self.can_go_forward() {
|
|
||||||
self.slide_id += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn go_backward(&mut self) {
|
|
||||||
if self.can_go_backward() {
|
|
||||||
self.slide_id -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Title: FC<()> = |cx, props| {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
h1 { "Title" }
|
|
||||||
p {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
const Slide1: FC<()> = |cx, props| {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
h1 { "Slide1" }
|
|
||||||
p {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
const Slide2: FC<()> = |cx, props| {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
h1 { "Slide2" }
|
|
||||||
p {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
const Slide3: FC<()> = |cx, props| {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
h1 { "Slide3" }
|
|
||||||
p {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
const End: FC<()> = |cx, props| {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
h1 { "End" }
|
|
||||||
p {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
use std::cell::Cell;
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_core::{
|
|
||||||
nodes::{VElement, VText},
|
|
||||||
ElementId,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
env_logger::init();
|
|
||||||
dioxus::desktop::launch(Example, |c| c);
|
|
||||||
}
|
|
||||||
|
|
||||||
const STYLE: &str = r#"
|
|
||||||
body {background-color: powderblue;}
|
|
||||||
h1 {color: blue;}
|
|
||||||
p {color: red;}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
const Example: FC<()> = |cx, props| {
|
|
||||||
cx.render(rsx! {
|
|
||||||
Fragment {
|
|
||||||
Fragment {
|
|
||||||
Fragment {
|
|
||||||
"h1"
|
|
||||||
div {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"h2"
|
|
||||||
}
|
|
||||||
"h3"
|
|
||||||
}
|
|
||||||
"h4"
|
|
||||||
div { "h5" }
|
|
||||||
button { }
|
|
||||||
Child {}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
const Child: FC<()> = |cx, props| {
|
|
||||||
cx.render(rsx!(
|
|
||||||
h1 {"1" }
|
|
||||||
h1 {"2" }
|
|
||||||
h1 {"3" }
|
|
||||||
h1 {"4" }
|
|
||||||
))
|
|
||||||
};
|
|
||||||
|
|
||||||
// this is a bad case that hurts our subtree memoization :(
|
|
||||||
const AbTest: FC<()> = |cx, props| {
|
|
||||||
if 1 == 2 {
|
|
||||||
cx.render(rsx!(
|
|
||||||
h1 {"1"}
|
|
||||||
h1 {"2"}
|
|
||||||
h1 {"3"}
|
|
||||||
h1 {"4"}
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
cx.render(rsx!(
|
|
||||||
h1 {"1"}
|
|
||||||
h1 {"2"}
|
|
||||||
h2 {"basd"}
|
|
||||||
h1 {"4"}
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
+43
-45
@@ -48,62 +48,60 @@ const App: FC<()> = |cx, props| {
|
|||||||
_ => "items",
|
_ => "items",
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.render(rsx! {
|
rsx!(cx, div { id: "app"
|
||||||
div { id: "app"
|
style {"{STYLE}"}
|
||||||
style {"{STYLE}"}
|
div {
|
||||||
div {
|
header { class: "header"
|
||||||
header { class: "header"
|
h1 {"todos"}
|
||||||
h1 {"todos"}
|
input {
|
||||||
input {
|
class: "new-todo"
|
||||||
class: "new-todo"
|
placeholder: "What needs to be done?"
|
||||||
placeholder: "What needs to be done?"
|
value: "{draft}"
|
||||||
value: "{draft}"
|
oninput: move |evt| draft.set(evt.value())
|
||||||
oninput: move |evt| draft.set(evt.value())
|
}
|
||||||
|
}
|
||||||
|
{todolist}
|
||||||
|
{(!todos.is_empty()).then(|| rsx!(
|
||||||
|
footer {
|
||||||
|
span { strong {"{items_left}"} span {"{item_text} left"} }
|
||||||
|
ul { class: "filters"
|
||||||
|
li { class: "All", a { href: "", onclick: move |_| filter.set(FilterState::All), "All" }}
|
||||||
|
li { class: "Active", a { href: "active", onclick: move |_| filter.set(FilterState::Active), "Active" }}
|
||||||
|
li { class: "Completed", a { href: "completed", onclick: move |_| filter.set(FilterState::Completed), "Completed" }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{todolist}
|
))}
|
||||||
{(!todos.is_empty()).then(|| rsx!(
|
}
|
||||||
footer {
|
footer { class: "info"
|
||||||
span { strong {"{items_left}"} span {"{item_text} left"} }
|
p {"Double-click to edit a todo"}
|
||||||
ul { class: "filters"
|
p { "Created by ", a { "jkelleyrtp", href: "http://github.com/jkelleyrtp/" }}
|
||||||
li { class: "All", a { href: "", onclick: move |_| filter.set(FilterState::All), "All" }}
|
p { "Part of ", a { "TodoMVC", href: "http://todomvc.com" }}
|
||||||
li { class: "Active", a { href: "active", onclick: move |_| filter.set(FilterState::Active), "Active" }}
|
|
||||||
li { class: "Completed", a { href: "completed", onclick: move |_| filter.set(FilterState::Completed), "Completed" }}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
))}
|
|
||||||
}
|
|
||||||
footer { class: "info"
|
|
||||||
p {"Double-click to edit a todo"}
|
|
||||||
p { "Created by ", a { "jkelleyrtp", href: "http://github.com/jkelleyrtp/" }}
|
|
||||||
p { "Part of ", a { "TodoMVC", href: "http://todomvc.com" }}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Props)]
|
#[derive(PartialEq, Props)]
|
||||||
pub struct TodoEntryProps {
|
pub struct TodoEntryProps {
|
||||||
todo: std::rc::Rc<TodoItem>,
|
todo: Rc<TodoItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn TodoEntry<'a>(cx: Context<'a>, TodoEntryProps { todo }: &'a TodoEntryProps) -> DomTree<'a> {
|
pub fn TodoEntry<'a>(cx: Context<'a>, props: &TodoEntryProps) -> DomTree<'a> {
|
||||||
let is_editing = use_state(cx, || false);
|
let is_editing = use_state(cx, || false);
|
||||||
let contents = "";
|
let contents = use_state(cx, || String::from(""));
|
||||||
|
let todo = &props.todo;
|
||||||
|
|
||||||
cx.render(rsx! (
|
rsx!(cx, li {
|
||||||
li {
|
"{todo.id}"
|
||||||
"{todo.id}"
|
input {
|
||||||
input {
|
class: "toggle"
|
||||||
class: "toggle"
|
r#type: "checkbox"
|
||||||
r#type: "checkbox"
|
"{todo.checked}"
|
||||||
"{todo.checked}"
|
|
||||||
}
|
|
||||||
{is_editing.then(|| rsx!{
|
|
||||||
input {
|
|
||||||
value: "{contents}"
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
}
|
}
|
||||||
))
|
{is_editing.then(|| rsx!{
|
||||||
|
input {
|
||||||
|
value: "{contents}"
|
||||||
|
oninput: move |evt| contents.set(evt.value())
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
//! Example: Webview Renderer
|
|
||||||
//! -------------------------
|
|
||||||
//!
|
|
||||||
//! This example shows how to use the dioxus_desktop crate to build a basic desktop application.
|
|
||||||
//!
|
|
||||||
//! Under the hood, the dioxus_desktop crate bridges a native Dioxus VirtualDom with a custom prebuit application running
|
|
||||||
//! in the webview runtime. Custom handlers are provided for the webview instance to consume patches and emit user events
|
|
||||||
//! into the native VDom instance.
|
|
||||||
//!
|
|
||||||
//! Currently, NodeRefs won't work properly, but all other event functionality will.
|
|
||||||
#![allow(non_upper_case_globals, non_snake_case)]
|
|
||||||
|
|
||||||
use dioxus::{events::on::MouseEvent, prelude::*};
|
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
|
||||||
env_logger::init();
|
|
||||||
dioxus::desktop::launch(App, |c| c)
|
|
||||||
}
|
|
||||||
|
|
||||||
static App: FC<()> = |cx, props| {
|
|
||||||
let state = use_state(cx, || String::from("hello"));
|
|
||||||
let clear_text = state == "hello";
|
|
||||||
|
|
||||||
dbg!("rednering parent");
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
h1 {"{state}"}
|
|
||||||
CalculatorKey { name: "key-clear", onclick: move |_| state.modify().push_str("hello"), "{clear_text}" }
|
|
||||||
CalculatorKey { name: "key-sign", onclick: move |_| { state.modify().pop(); }, "±"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Props)]
|
|
||||||
struct CalculatorKeyProps<'a> {
|
|
||||||
name: &'static str,
|
|
||||||
onclick: &'a dyn Fn(MouseEvent),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn CalculatorKey<'a>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomTree<'a> {
|
|
||||||
cx.render(rsx! {
|
|
||||||
button {
|
|
||||||
class: "calculator-key {props.name}"
|
|
||||||
onclick: {props.onclick}
|
|
||||||
{cx.children()}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user