aughr
This commit is contained in:
parent
ead504a483
commit
bc9ade91fe
3187
Cargo.lock
generated
3187
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -4,8 +4,11 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clay-layout = "0.2.0"
|
||||
enum_dispatch = "0.3.13"
|
||||
iced = "0.13.1"
|
||||
font-kit = "0.14.2"
|
||||
minifb = "0.28.0"
|
||||
raqote = "0.8.5"
|
||||
test-case = "3.3.1"
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -39,13 +39,17 @@
|
|||
xorg.libXrandr
|
||||
wayland
|
||||
libxkbcommon
|
||||
rust-cbindgen
|
||||
];
|
||||
|
||||
LD_LIBRARY_PATH =
|
||||
builtins.foldl' (a: b: "${a}:${b}/lib") "${pkgs.vulkan-loader}/lib" buildInputs;
|
||||
|
||||
shell = ''
|
||||
echo "Hello from nix dev shell"
|
||||
# NIX_LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
||||
|
||||
shellHook = ''
|
||||
# export LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH
|
||||
# export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}/lib";
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
137
src/app/bin.rs
137
src/app/bin.rs
|
@ -1,7 +1,140 @@
|
|||
use std::{any::Any, cell::RefCell, rc::Rc};
|
||||
|
||||
use clay_layout::{
|
||||
Clay,
|
||||
bindings::Clay_TextElementConfig,
|
||||
elements::{
|
||||
CornerRadius,
|
||||
rectangle::Rectangle,
|
||||
text::{Text, TextElementConfig},
|
||||
},
|
||||
fixed,
|
||||
id::Id,
|
||||
layout::Layout,
|
||||
math::Dimensions,
|
||||
};
|
||||
|
||||
use font_kit::{family_name::FamilyName, properties::Properties, source::SystemSource};
|
||||
use gui::GUI;
|
||||
use minifb::{Window, WindowOptions};
|
||||
use raqote::{DrawOptions, DrawTarget, SolidSource};
|
||||
|
||||
mod gui;
|
||||
|
||||
fn main() -> Result<(), iced::Error> {
|
||||
GUI::run("Openbirch GUI")
|
||||
fn main() {
|
||||
let clay = Clay::new((800., 600.).into());
|
||||
|
||||
let mut window = Window::new("Raqote", 800, 40, WindowOptions {
|
||||
borderless: true,
|
||||
scale_mode: minifb::ScaleMode::Center,
|
||||
resize: true,
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let font = SystemSource::new()
|
||||
.select_best_match(&[FamilyName::Monospace], &Properties::new())
|
||||
.unwrap()
|
||||
.load()
|
||||
.unwrap();
|
||||
|
||||
window.set_target_fps(60);
|
||||
|
||||
let mut size = window.get_size();
|
||||
let mut dt = DrawTarget::new(size.0 as i32, size.1 as i32);
|
||||
|
||||
clay.measure_text_function(|text, config| {
|
||||
let config: Clay_TextElementConfig = unsafe {
|
||||
*std::mem::transmute::<TextElementConfig, *mut Clay_TextElementConfig>(config)
|
||||
};
|
||||
|
||||
Dimensions {
|
||||
width: config.fontSize as f32,
|
||||
height: config.fontSize as f32 * text.len() as f32,
|
||||
}
|
||||
});
|
||||
|
||||
loop {
|
||||
dt.clear(SolidSource::from_unpremultiplied_argb(
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
));
|
||||
clay.begin();
|
||||
|
||||
// Adds a red rectangle with a corner radius of 5.
|
||||
// The Layout makes the rectangle have a width and height of 50.
|
||||
clay.with(
|
||||
[
|
||||
Id::new("red_rectangle"),
|
||||
Layout::new().width(fixed!(50.)).height(fixed!(50.)).end(),
|
||||
Rectangle::new()
|
||||
.color((0xFF, 0x00, 0x00).into())
|
||||
.corner_radius(CornerRadius::All(5.))
|
||||
.end(),
|
||||
],
|
||||
|c| {
|
||||
c.with(
|
||||
[
|
||||
Id::new("test_text"),
|
||||
Layout::new().end(),
|
||||
Rectangle::new().color((0xFF, 0xFF, 0xFF).into()).end(),
|
||||
// Text::new().color((0xFF, 0xFF, 0xFF).into()).end()
|
||||
],
|
||||
|_| {},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
// Return the list of render commands of your layout
|
||||
let render_commands = clay.end();
|
||||
|
||||
for command in render_commands {
|
||||
// println!("Id of the element: {}", command.id); // Note: Ids are in fact numbers generated by Clay
|
||||
// println!("Bounding box: {:?}", command.bounding_box);
|
||||
// println!("Type and config: {:?}", command.config);
|
||||
|
||||
match command.config {
|
||||
clay_layout::render_commands::RenderCommandConfig::Rectangle(rectangle) => {
|
||||
dt.fill_rect(
|
||||
command.bounding_box.x,
|
||||
command.bounding_box.y,
|
||||
command.bounding_box.width,
|
||||
command.bounding_box.height,
|
||||
&raqote::Source::Solid(SolidSource {
|
||||
r: (rectangle.color.r * 255.0) as u8,
|
||||
g: (rectangle.color.g * 255.0) as u8,
|
||||
b: (rectangle.color.b * 255.0) as u8,
|
||||
a: (rectangle.color.a * 255.0) as u8,
|
||||
}),
|
||||
&DrawOptions::new(),
|
||||
);
|
||||
}
|
||||
clay_layout::render_commands::RenderCommandConfig::Border(border_container) => {
|
||||
todo!()
|
||||
}
|
||||
clay_layout::render_commands::RenderCommandConfig::Text(_, text) => todo!(),
|
||||
clay_layout::render_commands::RenderCommandConfig::Image(image) => todo!(),
|
||||
clay_layout::render_commands::RenderCommandConfig::ScissorStart() => todo!(),
|
||||
clay_layout::render_commands::RenderCommandConfig::ScissorEnd() => todo!(),
|
||||
clay_layout::render_commands::RenderCommandConfig::Custom(custom) => todo!(),
|
||||
clay_layout::render_commands::RenderCommandConfig::None() => {}
|
||||
}
|
||||
}
|
||||
|
||||
if window.is_key_down(minifb::Key::Escape) {
|
||||
break;
|
||||
}
|
||||
|
||||
let (width, height) = window.get_size();
|
||||
|
||||
if width as i32 != dt.width() || height as i32 != dt.height() {
|
||||
dt = DrawTarget::new(width as i32, height as i32);
|
||||
clay.layout_dimensions((width as f32, height as f32).into());
|
||||
size = (width, height);
|
||||
// window.update();
|
||||
} else {
|
||||
window
|
||||
.update_with_buffer(dt.get_data(), size.0, size.1)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum Line {
|
||||
Text(String)
|
||||
}
|
8
src/app/gui/math_segments.rs
Normal file
8
src/app/gui/math_segments.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
use enum_dispatch::enum_dispatch;
|
||||
use libopenbirch::node::{Node, NodeEnum};
|
||||
|
||||
pub trait MathSegment {
|
||||
}
|
||||
|
||||
impl MathSegment for NodeEnum {
|
||||
}
|
|
@ -1,96 +1,27 @@
|
|||
use iced::{Element, Length, Task, widget::text};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Message {
|
||||
CreateLine(Option<usize>, Line, bool),
|
||||
ChangeLine(usize, Line),
|
||||
}
|
||||
use libopenbirch::node::{
|
||||
NodeEnum, add::Add, constant::Constant, divide::Divide, multiply::Multiply, symbol::Symbol,
|
||||
};
|
||||
use math_segments::MathSegment;
|
||||
|
||||
mod line;
|
||||
use line::Line;
|
||||
mod math_segments;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GUI {
|
||||
lines: Vec<Line>,
|
||||
current_line: usize,
|
||||
meth: Vec<Rc<dyn MathSegment>>,
|
||||
}
|
||||
|
||||
impl GUI {
|
||||
pub fn run(title: &'static str) -> Result<(), iced::Error> {
|
||||
iced::application(title, Self::update, Self::view)
|
||||
.settings(iced::Settings {
|
||||
default_font: iced::font::Font::MONOSPACE,
|
||||
antialiasing: true,
|
||||
..Default::default()
|
||||
})
|
||||
.theme(|_| iced::Theme::Nord)
|
||||
.centered()
|
||||
.run_with(move || Self::new())
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
let a = Constant::new(69.0).into();
|
||||
let b = Constant::new(420.0).into();
|
||||
let c: NodeEnum = Add::new(a, b).into();
|
||||
let d = Symbol::new_from_str("x").into();
|
||||
let e = Divide::new(c.clone(), d).into();
|
||||
let f = Multiply::new(e, c);
|
||||
|
||||
fn new() -> (Self, Task<Message>) {
|
||||
let s = Self {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
(
|
||||
s,
|
||||
Task::done(Message::CreateLine(
|
||||
None,
|
||||
Line::Text("Testline".to_owned()),
|
||||
true,
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::CreateLine(idx, line, focus) => {
|
||||
let idx = if let Some(idx) = idx {
|
||||
idx
|
||||
} else {
|
||||
self.lines.len()
|
||||
};
|
||||
self.lines.insert(idx, line);
|
||||
if focus {
|
||||
self.current_line = idx;
|
||||
}
|
||||
}
|
||||
Message::ChangeLine(idx, text) => {
|
||||
let r = self.lines.get_mut(idx);
|
||||
if let Some(r) = r {
|
||||
std::mem::replace(r, text);
|
||||
} else {
|
||||
// TODO: Error message to user
|
||||
}
|
||||
}
|
||||
Self {
|
||||
meth: vec![Rc::new(NodeEnum::Multiply(f))],
|
||||
}
|
||||
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<Message> {
|
||||
iced::widget::Column::from_vec(
|
||||
self.lines
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(move |(i, line)| {
|
||||
match line {
|
||||
Line::Text(text) => iced::widget::text_input("", text)
|
||||
.width(Length::Fill)
|
||||
.on_input(move |s| Message::ChangeLine(i, Line::Text(s)))
|
||||
.on_submit(Message::CreateLine(
|
||||
Some(i + 1),
|
||||
Line::Text("".to_owned()),
|
||||
true,
|
||||
)),
|
||||
}
|
||||
.into()
|
||||
})
|
||||
.collect::<Vec<Element<Message>>>(),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use super::{constant::Constant, Environment, Node, NodeEnum, Precedence};
|
||||
use super::{Environment, Node, NodeEnum, Precedence, constant::Constant};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub struct Add {
|
||||
|
@ -47,4 +47,12 @@ impl Add {
|
|||
right: Rc::new(right),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_left(&self) -> Rc<NodeEnum> {
|
||||
self.left.clone()
|
||||
}
|
||||
|
||||
pub fn get_right(&self) -> Rc<NodeEnum> {
|
||||
self.right.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,24 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use super::{empty::Empty, symbol::Symbol, Environment, Node, NodeEnum, Precedence};
|
||||
use super::{Environment, Node, NodeEnum, Precedence, empty::Empty, symbol::Symbol};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||
pub struct Assign {
|
||||
left: Symbol,
|
||||
left: Rc<NodeEnum>,
|
||||
right: Rc<NodeEnum>,
|
||||
}
|
||||
|
||||
impl Node for Assign {
|
||||
fn evaluate(&self, env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
|
||||
env.insert(self.left.get_value(), self.right.clone());
|
||||
Ok(Empty::EMPTY.clone())
|
||||
if let NodeEnum::Symbol(symbol) = self.left.as_ref() {
|
||||
env.insert(symbol.get_value(), self.right.clone());
|
||||
Ok(Empty::EMPTY.clone())
|
||||
} else {
|
||||
Err(format!(
|
||||
"Cannot assign to a {}",
|
||||
self.left.as_string(Some(env))
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn as_string(&self, env: Option<&Environment>) -> String {
|
||||
|
@ -26,3 +33,13 @@ impl Node for Assign {
|
|||
Precedence::Assign
|
||||
}
|
||||
}
|
||||
|
||||
impl Assign {
|
||||
pub fn get_left(&self) -> Rc<NodeEnum> {
|
||||
self.left.clone()
|
||||
}
|
||||
|
||||
pub fn get_right(&self) -> Rc<NodeEnum> {
|
||||
self.left.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,4 +47,12 @@ impl Divide {
|
|||
right: Rc::new(right),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_left(&self) -> Rc<NodeEnum> {
|
||||
self.left.clone()
|
||||
}
|
||||
|
||||
pub fn get_right(&self) -> Rc<NodeEnum> {
|
||||
self.right.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,4 +47,12 @@ impl Multiply {
|
|||
right: Rc::new(right),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_left(&self) -> Rc<NodeEnum> {
|
||||
self.left.clone()
|
||||
}
|
||||
|
||||
pub fn get_right(&self) -> Rc<NodeEnum> {
|
||||
self.right.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use super::{constant::Constant, Environment, Node, NodeEnum, Precedence};
|
||||
use super::{Environment, Node, NodeEnum, Precedence, constant::Constant};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub struct Subtract {
|
||||
|
@ -47,4 +47,12 @@ impl Subtract {
|
|||
right: Rc::new(right),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_left(&self) -> Rc<NodeEnum> {
|
||||
self.left.clone()
|
||||
}
|
||||
|
||||
pub fn get_right(&self) -> Rc<NodeEnum> {
|
||||
self.right.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ impl Symbol {
|
|||
Self { value }
|
||||
}
|
||||
|
||||
pub fn new_from_str(str: String) -> Self {
|
||||
pub fn new_from_str(str: impl Into<String>) -> Self {
|
||||
let str = str.into();
|
||||
if let Some(value) = Symbol::STR_TO_ID_MAP.lock().unwrap().get(str.as_str()) {
|
||||
Self::new(value.clone())
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue