wip: enable more diffing
This commit is contained in:
1 parent
b5e5ef171a
commit
e8f29a8f8a
26 files changed
+1326
-367
No files matched your search
@@ -0,0 +1,136 @@
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font: 100 14px 'Roboto';
|
||||
}
|
||||
|
||||
button {
|
||||
display: block;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font-family: inherit;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
|
||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
button:active {
|
||||
box-shadow: inset 0px 0px 80px 0px rgba(0,0,0,0.25);
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
height: 100vh;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#app {
|
||||
width: 320px;
|
||||
height: 520px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.calculator {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: black;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#wrapper .calculator {
|
||||
box-shadow: 0px 0px 20px 0px #aaa;
|
||||
}
|
||||
|
||||
.calculator-display {
|
||||
color: white;
|
||||
background: #1c191c;
|
||||
line-height: 130px;
|
||||
font-size: 6em;
|
||||
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.auto-scaling-text {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.calculator-display .auto-scaling-text {
|
||||
padding: 0 30px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
transform-origin: right;
|
||||
}
|
||||
|
||||
.calculator-keypad {
|
||||
height: 400px;
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.calculator .input-keys {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.calculator .function-keys {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.calculator .digit-keys {
|
||||
background: #e0e0e7;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
|
||||
.calculator-key {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-top: 1px solid #777;
|
||||
border-right: 1px solid #666;
|
||||
text-align: center;
|
||||
line-height: 80px;
|
||||
}
|
||||
.calculator .function-keys .calculator-key {
|
||||
font-size: 2em;
|
||||
}
|
||||
.calculator .function-keys .key-multiply {
|
||||
line-height: 50px;
|
||||
}
|
||||
.calculator .digit-keys .calculator-key {
|
||||
font-size: 2.25em;
|
||||
}
|
||||
.calculator .digit-keys .key-0 {
|
||||
width: 160px;
|
||||
text-align: left;
|
||||
padding-left: 32px;
|
||||
}
|
||||
.calculator .digit-keys .key-dot {
|
||||
padding-top: 1em;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
.calculator .operator-keys .calculator-key {
|
||||
color: white;
|
||||
border-right: 0;
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
.calculator .function-keys {
|
||||
background: linear-gradient(to bottom, rgba(202,202,204,1) 0%, rgba(196,194,204,1) 100%);
|
||||
}
|
||||
.calculator .operator-keys {
|
||||
background: linear-gradient(to bottom, rgba(252,156,23,1) 0%, rgba(247,126,27,1) 100%);
|
||||
}
|
||||
@@ -98,16 +98,16 @@ static App: FC<()> = |cx| {
|
||||
CalculatorKey { name: "key-0", onclick: move |_| input_digit(0), "0" }
|
||||
CalculatorKey { name: "key-dot", onclick: move |_| input_dot(), "●" }
|
||||
|
||||
{(1..9).map(|k| rsx!{
|
||||
{(1..9).map(move |k| rsx!{
|
||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| input_digit(k), "{k}" }
|
||||
})}
|
||||
}
|
||||
div { class: "operator-keys"
|
||||
CalculatorKey { name:"key-divide", onclick: move |_| operator.set(Some(Operator::Div)) "÷" }
|
||||
CalculatorKey { name:"key-multiply", onclick: move |_| operator.set(Some(Operator::Mul)) "×" }
|
||||
CalculatorKey { name:"key-subtract", onclick: move |_| operator.set(Some(Operator::Sub)) "−" }
|
||||
CalculatorKey { name:"key-add", onclick: move |_| operator.set(Some(Operator::Add)) "+" }
|
||||
CalculatorKey { name:"key-equals", onclick: move |_| perform_operation() "=" }
|
||||
CalculatorKey { name: "key-divide", onclick: move |_| operator.set(Some(Operator::Div)) "÷" }
|
||||
CalculatorKey { name: "key-multiply", onclick: move |_| operator.set(Some(Operator::Mul)) "×" }
|
||||
CalculatorKey { name: "key-subtract", onclick: move |_| operator.set(Some(Operator::Sub)) "−" }
|
||||
CalculatorKey { name: "key-add", onclick: move |_| operator.set(Some(Operator::Add)) "+" }
|
||||
CalculatorKey { name: "key-equals", onclick: move |_| perform_operation() "=" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,10 @@ static App: FC<()> = |cx| {
|
||||
|
||||
#[derive(Props)]
|
||||
struct CalculatorKeyProps<'a> {
|
||||
/// Name!
|
||||
name: &'static str,
|
||||
|
||||
/// Click!
|
||||
onclick: &'a dyn Fn(MouseEvent),
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
fn main() {}
|
||||
|
||||
struct Title(String);
|
||||
|
||||
struct Position([f32; 3]);
|
||||
|
||||
struct Velocity([f32; 3]);
|
||||
|
||||
type Batch<T> = fn(&mut T) -> ();
|
||||
|
||||
static Atom: Batch<(Title, Position, Velocity)> = |_| {};
|
||||
|
||||
enum VNode<'a> {
|
||||
El(El<'a>),
|
||||
Text(&'a str),
|
||||
Fragment(&'a [VNode<'a>]),
|
||||
}
|
||||
struct El<'a> {
|
||||
name: &'static str,
|
||||
key: Option<&'a str>,
|
||||
attrs: &'a [(&'static str, AttrType<'a>)],
|
||||
children: &'a [El<'a>],
|
||||
}
|
||||
enum AttrType<'a> {
|
||||
Numeric(usize),
|
||||
Text(&'a str),
|
||||
}
|
||||
|
||||
fn example() {
|
||||
use AttrType::Numeric;
|
||||
let el = El {
|
||||
name: "div",
|
||||
attrs: &[("type", Numeric(10)), ("type", Numeric(10))],
|
||||
key: None,
|
||||
children: &[],
|
||||
};
|
||||
}
|
||||
|
||||
use dioxus::prelude::bumpalo::Bump;
|
||||
trait IntoVnode {
|
||||
fn into_vnode<'a>(self, b: &'a Bump) -> VNode<'a>;
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for VNode<'a> {
|
||||
type Item = VNode<'a>;
|
||||
type IntoIter = std::iter::Once<VNode<'a>>;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
std::iter::once(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn take_iterable<F: IntoVnode>(f: impl IntoIterator<Item = F>) {
|
||||
let iter = f.into_iter();
|
||||
let b = Bump::new();
|
||||
for f in iter {
|
||||
let v = f.into_vnode(&b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
let (g, set_g) = use_state(&cx, || 0);
|
||||
let v = (0..10).map(move |f| {
|
||||
rsx!(li {
|
||||
onclick: move |_| set_g(10)
|
||||
})
|
||||
});
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
{v}
|
||||
}
|
||||
})
|
||||
};
|
||||
+42
-27
@@ -4,51 +4,54 @@
|
||||
//! Some components benefit through the use of "Models". Models are a single block of encapsulated state that allow mutative
|
||||
//! methods to be performed on them. Dioxus exposes the ability to use the model pattern through the "use_model" hook.
|
||||
//!
|
||||
//! Models are commonly used in the "Model-View-Component" approach for building UI state.
|
||||
//!
|
||||
//! `use_model` is basically just a fancy wrapper around set_state, but saves a "working copy" of the new state behind a
|
||||
//! RefCell. To modify the working copy, you need to call "modify" which returns the RefMut. This makes it easy to write
|
||||
//! RefCell. To modify the working copy, you need to call "get_mut" which returns the RefMut. This makes it easy to write
|
||||
//! fully encapsulated apps that retain a certain feel of native Rusty-ness. A calculator app is a good example of when this
|
||||
//! is useful.
|
||||
//!
|
||||
//! Do note that "get_mut" returns a `RefMut` (a lock over a RefCell). If two `RefMut`s are held at the same time (ie in a loop)
|
||||
//! the RefCell will panic and crash. You can use `try_get_mut` or `.modify` to avoid this problem, or just not hold two
|
||||
//! RefMuts at the same time.
|
||||
|
||||
use dioxus::events::on::*;
|
||||
use dioxus::prelude::*;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
dioxus::webview::launch(App)
|
||||
}
|
||||
|
||||
static App: FC<()> = |cx| {
|
||||
let state = use_model(&cx, || CalculatorState::new());
|
||||
let calc = use_model(&cx, || Calculator::new());
|
||||
|
||||
let clear_display = state.display_value.eq("0");
|
||||
let clear_display = calc.display_value.eq("0");
|
||||
let clear_text = if clear_display { "C" } else { "AC" };
|
||||
let formatted = state.formatted();
|
||||
let formatted = calc.formatted();
|
||||
|
||||
cx.render(rsx! {
|
||||
div { class: "calculator", onkeydown: move |evt| state.modify().handle_keydown(evt),
|
||||
div { class: "calculator-display", "{formatted}"}
|
||||
div { class: "calculator", onkeydown: move |evt| calc.get_mut().handle_keydown(evt),
|
||||
div { class: "calculator-display","{formatted}"}
|
||||
div { class: "input-keys"
|
||||
div { class: "function-keys"
|
||||
CalculatorKey { name: "key-clear", onclick: move |_| state.modify().clear_display() "{clear_text}" }
|
||||
CalculatorKey { name: "key-sign", onclick: move |_| state.modify().toggle_sign(), "±"}
|
||||
CalculatorKey { name: "key-percent", onclick: move |_| state.modify().toggle_percent() "%"}
|
||||
// All there ways that the calculator may be modified:
|
||||
CalculatorKey { name: "key-clear", onclick: move |_| calc.get_mut().clear_display() "{clear_text}" }
|
||||
CalculatorKey { name: "key-sign", onclick: move |_| calc.modify(Calculator::toggle_sign), "±"}
|
||||
CalculatorKey { name: "key-percent", onclick: move |_| calc.modify(|f| f.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..9).map(|k| rsx!{
|
||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.modify().input_digit(k), "{k}" }
|
||||
CalculatorKey { name: "key-0", onclick: move |_| calc.get_mut().input_digit(0), "0" }
|
||||
CalculatorKey { name: "key-dot", onclick: move |_| calc.get_mut().input_dot(), "●" }
|
||||
{(1..9).map(move |k| rsx!{
|
||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| calc.get_mut().input_digit(k), "{k}" }
|
||||
})}
|
||||
}
|
||||
div { class: "operator-keys"
|
||||
CalculatorKey { name:"key-divide", onclick: move |_| state.modify().set_operator(Operator::Div) "÷" }
|
||||
CalculatorKey { name:"key-multiply", onclick: move |_| state.modify().set_operator(Operator::Mul) "×" }
|
||||
CalculatorKey { name:"key-subtract", onclick: move |_| state.modify().set_operator(Operator::Sub) "−" }
|
||||
CalculatorKey { name:"key-add", onclick: move |_| state.modify().set_operator(Operator::Add) "+" }
|
||||
CalculatorKey { name:"key-equals", onclick: move |_| state.modify().perform_operation() "=" }
|
||||
CalculatorKey { name:"key-divide", onclick: move |_| calc.get_mut().set_operator(Operator::Div) "÷" }
|
||||
CalculatorKey { name:"key-multiply", onclick: move |_| calc.get_mut().set_operator(Operator::Mul) "×" }
|
||||
CalculatorKey { name:"key-subtract", onclick: move |_| calc.get_mut().set_operator(Operator::Sub) "−" }
|
||||
CalculatorKey { name:"key-add", onclick: move |_| calc.get_mut().set_operator(Operator::Add) "+" }
|
||||
CalculatorKey { name:"key-equals", onclick: move |_| calc.get_mut().perform_operation() "=" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +59,7 @@ static App: FC<()> = |cx| {
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct CalculatorState {
|
||||
struct Calculator {
|
||||
display_value: String,
|
||||
operator: Option<Operator>,
|
||||
cur_val: f64,
|
||||
@@ -68,9 +71,10 @@ enum Operator {
|
||||
Mul,
|
||||
Div,
|
||||
}
|
||||
impl CalculatorState {
|
||||
|
||||
impl Calculator {
|
||||
fn new() -> Self {
|
||||
CalculatorState {
|
||||
Calculator {
|
||||
display_value: "0".to_string(),
|
||||
operator: None,
|
||||
cur_val: 0.0,
|
||||
@@ -118,7 +122,9 @@ impl CalculatorState {
|
||||
self.display_value.pop();
|
||||
}
|
||||
}
|
||||
fn set_operator(&mut self, operator: Operator) {}
|
||||
fn set_operator(&mut self, operator: Operator) {
|
||||
self.operator = Some(operator)
|
||||
}
|
||||
fn handle_keydown(&mut self, evt: KeyboardEvent) {
|
||||
match evt.key_code() {
|
||||
KeyCode::Backspace => self.backspace(),
|
||||
@@ -160,6 +166,10 @@ fn CalculatorKey<'a, 'r>(cx: Context<'a, CalculatorKeyProps<'r>>) -> VNode<'a> {
|
||||
use odl::use_model;
|
||||
mod odl {
|
||||
use super::*;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
/// Use model makes it easy to use "models" as state for components. To modify the model, call "modify" and a clone of the
|
||||
/// current model will be made, with a RefMut lock on it. Dioxus will never run your components multithreaded, so you can
|
||||
/// be relatively sure that this won't fail in practice
|
||||
@@ -208,9 +218,14 @@ mod odl {
|
||||
wip: RefCell::new(t),
|
||||
}
|
||||
}
|
||||
pub fn modify(&self) -> RefMut<'_, T> {
|
||||
pub fn get_mut(&self) -> RefMut<'_, T> {
|
||||
self.wip.borrow_mut()
|
||||
}
|
||||
pub fn modify(&self, f: impl FnOnce(&mut T)) {
|
||||
let mut g = self.get_mut();
|
||||
let r = g.deref_mut();
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
||||
@@ -2,9 +2,17 @@ use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
let (g, set_g) = use_state(&cx, || 0);
|
||||
let v = (0..10).map(|f| {
|
||||
rsx! {
|
||||
li {
|
||||
onclick: move |_| set_g(10)
|
||||
}
|
||||
}
|
||||
});
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
{v}
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
// mod iterator;
|
||||
// mod memo;
|
||||
mod iterators;
|
||||
mod listener;
|
||||
mod memo;
|
||||
|
||||
fn main() {}
|
||||
@@ -1,2 +0,0 @@
|
||||
mod iterator;
|
||||
mod memo;
|
||||
Reference in new issue
Block a user