frontend: the advoware GUI

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
2020-06-12 16:39:45 +02:00
parent 3837183199
commit 51b73d0978
68 changed files with 3499 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
mod state;
use self::state::{AppState, Event};
use orbtk::prelude::*;
widget! {
MainView<AppState> {
orientation: Orientation,
spacing: f64
}
}
impl Template for MainView {
fn template(mut self, id: Entity, ctx: &mut BuildContext) -> Self {
let entry = TextBox::create()
.vertical_alignment(Alignment::End)
.on_activate(move |ctxt, entity| {
ctxt.get_mut::<AppState>(id).send(Event::Create(entity));
})
.build(ctx);
let notes = Stack::create()
.orientation(Orientation::Vertical)
.spacing(4)
.build(ctx);
self.state.notes = notes;
let scroll_viewer = ScrollViewer::create()
.scroll_viewer_mode(("disabled", "auto"))
.child(notes)
.build(ctx);
self.name("main-view")
.orientation(Orientation::Vertical)
.margin(4)
.child(
Container::create()
.child(scroll_viewer)
.child(
ScrollIndicator::create()
.padding(2.0)
.scroll_offset(scroll_viewer)
.build(ctx),
)
.build(ctx)
)
.child(entry)
}
fn layout(&self) -> Box<dyn Layout> {
Box::new(StackLayout::new())
}
}
fn main() {
Application::new()
.window(|ctx| {
Window::create()
.title("Orbital To Do")
.position((500.0, 500.0))
.size(400.0, 400.0)
.child(MainView::create().build(ctx))
.build(ctx)
})
.run();
}

View File

@@ -0,0 +1,92 @@
use orbtk::prelude::*;
use std::collections::VecDeque;
#[derive(Debug)]
pub enum Event {
Create(Entity),
Delete(Entity),
}
#[derive(AsAny, Default)]
pub struct AppState {
events: VecDeque<Event>,
pub notes: Entity,
count: u32,
}
impl AppState {
fn append_note(&self, ctx: &mut Context, copy: String) {
let id = ctx.entity;
let bctx = &mut ctx.build_context();
let text = TextBox::create().text(copy);
let container = Stack::create()
.orientation(Orientation::Horizontal)
.vertical_alignment(Alignment::Start)
.child(text.build(bctx))
.build(bctx);
let button = Button::create()
.horizontal_alignment(Alignment::End)
.text("Delete")
.on_click(move |ctxt, _| {
ctxt.get_mut::<AppState>(id)
.events
.push_back(Event::Delete(container));
true
})
.build(bctx);
bctx.append_child(container, button);
bctx.append_child(self.notes, container);
}
fn fetch_text(ctx: &mut Context, entity: Entity) -> Option<String> {
let mut widget = ctx.get_widget(entity);
let entry = widget.get_mut::<String16>("text");
if entry.is_empty() {
return None;
}
let copy = entry.to_string();
entry.clear();
Some(copy)
}
pub fn send(&mut self, event: Event) {
self.events.push_back(event);
}
}
impl State for AppState {
fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
if let Some(event) = self.events.pop_front() {
match event {
// Create and append the note to the UI.
Event::Create(entity) => {
if let Some(copy) = Self::fetch_text(ctx, entity) {
self.append_note(ctx, copy);
let count = self.count + 1;
self.count = count;
if count == 1 {
ctx.widget().set::<f64>("spacing", 12.0);
}
}
}
// Delete the note of the given ID from the UI.
Event::Delete(id) => {
ctx.remove_child_from(id, self.notes);
let count = self.count - 1;
self.count = count;
if count == 0 {
ctx.widget().set::<f64>("spacing", 0.0);
}
}
}
}
}
}