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"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
clay-layout = "0.2.0"
|
||||||
enum_dispatch = "0.3.13"
|
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"
|
test-case = "3.3.1"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
|
@ -39,13 +39,17 @@
|
||||||
xorg.libXrandr
|
xorg.libXrandr
|
||||||
wayland
|
wayland
|
||||||
libxkbcommon
|
libxkbcommon
|
||||||
|
rust-cbindgen
|
||||||
];
|
];
|
||||||
|
|
||||||
LD_LIBRARY_PATH =
|
LD_LIBRARY_PATH =
|
||||||
builtins.foldl' (a: b: "${a}:${b}/lib") "${pkgs.vulkan-loader}/lib" buildInputs;
|
builtins.foldl' (a: b: "${a}:${b}/lib") "${pkgs.vulkan-loader}/lib" buildInputs;
|
||||||
|
|
||||||
shell = ''
|
# NIX_LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
||||||
echo "Hello from nix dev shell"
|
|
||||||
|
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 gui::GUI;
|
||||||
|
use minifb::{Window, WindowOptions};
|
||||||
|
use raqote::{DrawOptions, DrawTarget, SolidSource};
|
||||||
|
|
||||||
mod gui;
|
mod gui;
|
||||||
|
|
||||||
fn main() -> Result<(), iced::Error> {
|
fn main() {
|
||||||
GUI::run("Openbirch GUI")
|
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)]
|
use libopenbirch::node::{
|
||||||
enum Message {
|
NodeEnum, add::Add, constant::Constant, divide::Divide, multiply::Multiply, symbol::Symbol,
|
||||||
CreateLine(Option<usize>, Line, bool),
|
};
|
||||||
ChangeLine(usize, Line),
|
use math_segments::MathSegment;
|
||||||
}
|
|
||||||
|
|
||||||
mod line;
|
mod math_segments;
|
||||||
use line::Line;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct GUI {
|
pub struct GUI {
|
||||||
lines: Vec<Line>,
|
meth: Vec<Rc<dyn MathSegment>>,
|
||||||
current_line: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GUI {
|
impl GUI {
|
||||||
pub fn run(title: &'static str) -> Result<(), iced::Error> {
|
pub fn new() -> Self {
|
||||||
iced::application(title, Self::update, Self::view)
|
let a = Constant::new(69.0).into();
|
||||||
.settings(iced::Settings {
|
let b = Constant::new(420.0).into();
|
||||||
default_font: iced::font::Font::MONOSPACE,
|
let c: NodeEnum = Add::new(a, b).into();
|
||||||
antialiasing: true,
|
let d = Symbol::new_from_str("x").into();
|
||||||
..Default::default()
|
let e = Divide::new(c.clone(), d).into();
|
||||||
})
|
let f = Multiply::new(e, c);
|
||||||
.theme(|_| iced::Theme::Nord)
|
|
||||||
.centered()
|
|
||||||
.run_with(move || Self::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new() -> (Self, Task<Message>) {
|
Self {
|
||||||
let s = Self {
|
meth: vec![Rc::new(NodeEnum::Multiply(f))],
|
||||||
..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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 std::rc::Rc;
|
||||||
|
|
||||||
use super::{constant::Constant, Environment, Node, NodeEnum, Precedence};
|
use super::{Environment, Node, NodeEnum, Precedence, constant::Constant};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||||
pub struct Add {
|
pub struct Add {
|
||||||
|
@ -47,4 +47,12 @@ impl Add {
|
||||||
right: Rc::new(right),
|
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 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)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||||
pub struct Assign {
|
pub struct Assign {
|
||||||
left: Symbol,
|
left: Rc<NodeEnum>,
|
||||||
right: Rc<NodeEnum>,
|
right: Rc<NodeEnum>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node for Assign {
|
impl Node for Assign {
|
||||||
fn evaluate(&self, env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
|
fn evaluate(&self, env: &mut Environment) -> Result<Rc<NodeEnum>, String> {
|
||||||
env.insert(self.left.get_value(), self.right.clone());
|
if let NodeEnum::Symbol(symbol) = self.left.as_ref() {
|
||||||
Ok(Empty::EMPTY.clone())
|
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 {
|
fn as_string(&self, env: Option<&Environment>) -> String {
|
||||||
|
@ -26,3 +33,13 @@ impl Node for Assign {
|
||||||
Precedence::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),
|
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),
|
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 std::rc::Rc;
|
||||||
|
|
||||||
use super::{constant::Constant, Environment, Node, NodeEnum, Precedence};
|
use super::{Environment, Node, NodeEnum, Precedence, constant::Constant};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||||
pub struct Subtract {
|
pub struct Subtract {
|
||||||
|
@ -47,4 +47,12 @@ impl Subtract {
|
||||||
right: Rc::new(right),
|
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 }
|
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()) {
|
if let Some(value) = Symbol::STR_TO_ID_MAP.lock().unwrap().get(str.as_str()) {
|
||||||
Self::new(value.clone())
|
Self::new(value.clone())
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue