feat: reactivityl; vdom; rhei; styles; fs; image element
This commit is contained in:
95
src/app.rs
Normal file
95
src/app.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
use iced::widget::{column, container, row, scrollable, text, Space};
|
||||
use iced::{Alignment, Length, Theme};
|
||||
|
||||
use crate::interpreter::{Document, Element, Interpreter, RheiContext};
|
||||
use crate::renderer::render_element;
|
||||
use crate::Message;
|
||||
|
||||
pub struct GlintApp {
|
||||
pub doc: Document,
|
||||
pub vdom_roots: Vec<Element>,
|
||||
pub rhei: RheiContext,
|
||||
}
|
||||
|
||||
impl GlintApp {
|
||||
pub fn title(&self) -> String {
|
||||
"Glint Runtime - Native Renderer".to_string()
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> iced::Task<Message> {
|
||||
match message {
|
||||
Message::EventTriggered(script) => {
|
||||
if !script.is_empty() {
|
||||
self.rhei.execute_action(&script, &mut self.doc.variables);
|
||||
}
|
||||
}
|
||||
Message::InputChanged(Some(var), val) => {
|
||||
self.doc.variables.insert(var, val);
|
||||
}
|
||||
Message::ToggleChanged(Some(var), val) => {
|
||||
self.doc.variables.insert(var, val.to_string());
|
||||
}
|
||||
Message::SliderChanged(Some(var), val) => {
|
||||
self.doc.variables.insert(var.clone(), format!("{:.1}", val));
|
||||
if var == "volume_level" {
|
||||
self.doc.variables.insert("age".to_string(), val.to_string());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.vdom_roots = Interpreter::evaluate_vdom(
|
||||
&self.doc.roots,
|
||||
&self.doc.variables,
|
||||
&self.doc.components,
|
||||
&self.rhei,
|
||||
&self.doc.stylesheet,
|
||||
);
|
||||
|
||||
iced::Task::none()
|
||||
}
|
||||
|
||||
pub fn view(&self) -> iced::Element<'_, Message, Theme, iced::Renderer> {
|
||||
let mut content = column![].spacing(15).padding(20);
|
||||
|
||||
for root in &self.vdom_roots {
|
||||
if let Some(el) = render_element(root) {
|
||||
content = content.push(el);
|
||||
}
|
||||
}
|
||||
|
||||
let status_bar = container(self.build_status_bar(&self.doc.variables))
|
||||
.width(Length::Fill)
|
||||
.padding(10);
|
||||
|
||||
let layout = column![
|
||||
scrollable(content).width(Length::Fill).height(Length::Fill),
|
||||
iced::widget::rule::horizontal(1),
|
||||
status_bar,
|
||||
];
|
||||
|
||||
container(layout)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn build_status_bar<'a>(
|
||||
&self,
|
||||
scope: &std::collections::HashMap<String, String>,
|
||||
) -> iced::Element<'a, Message, Theme, iced::Renderer> {
|
||||
let slider_val = scope.get("volume_level")
|
||||
.and_then(|v| v.parse::<f64>().ok())
|
||||
.unwrap_or(0.0);
|
||||
|
||||
row![
|
||||
text("🟢 Runtime Active (VDOM + Rhai)").size(14),
|
||||
Space::new().width(Length::Fill),
|
||||
text(format!("Шаблонных узлов: {}", self.doc.roots.len())).size(14),
|
||||
Space::new().width(Length::Fixed(15.0)),
|
||||
text(format!("Слайдер ($volume_level): {:.1}", slider_val)).size(14),
|
||||
]
|
||||
.align_y(Alignment::Center)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user