feat: reactivityl; vdom; rhei; styles; fs; image element

This commit is contained in:
Faynot
2026-06-02 12:12:20 +03:00
commit f956b750e3
16 changed files with 7713 additions and 0 deletions

95
src/app.rs Normal file
View 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()
}
}