wip: enable more diffing

This commit is contained in:
Jonathan Kelley committed 2021-07-05 01:11:49 -04:00
1 parent b5e5ef171a
commit e8f29a8f8a
26 files changed
+1326 -367

No files matched your search

+136
View File
@@ -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%);
}
+9 -6
View File
@@ -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),
}
+60
View File
@@ -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);
}
}
+16
View File
@@ -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
View File
@@ -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)]
+9 -1
View File
@@ -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}
}
})
};
+7
View File
@@ -0,0 +1,7 @@
// mod iterator;
// mod memo;
mod iterators;
mod listener;
mod memo;
fn main() {}
-2
View File
@@ -1,2 +0,0 @@
mod iterator;
mod memo;