gui stuff

gui stuff
This commit is contained in:
FantasyPvP
2023-11-22 00:36:23 +00:00
parent 7f81232556
commit 1d08240981
4 changed files with 90 additions and 28 deletions
+2 -2
View File
@@ -59,8 +59,8 @@ impl Element {
#[derive(Clone)] #[derive(Clone)]
pub struct ColouredElement { pub struct ColouredElement {
frame: Vec<Vec<ScreenChar>>, pub frame: Vec<Vec<ScreenChar>>,
dimensions: (u8, u8) pub dimensions: (u8, u8)
} }
impl ColouredElement { impl ColouredElement {
+22 -4
View File
@@ -7,10 +7,14 @@ use alloc::{boxed::Box, string::{String, ToString}, vec, vec::Vec};
use vga::writers::{GraphicsWriter, PrimitiveDrawing}; use vga::writers::{GraphicsWriter, PrimitiveDrawing};
use crate::{print, printerr, println, std, std::application::{Application, Error}, user::bin::*}; use crate::{print, printerr, println, std, std::application::{Application, Error}, user::bin::*};
use crate::kernel::render::ScreenChar;
use crate::std::frame::ColouredElement;
use crate::std::io::{Color, write, Screen, Stdin, Serial}; use crate::std::io::{Color, write, Screen, Stdin, Serial};
use crate::std::random::Random; use crate::std::random::Random;
use crate::user::bin::gigachad_detector::GigachadDetector; use crate::user::bin::gigachad_detector::GigachadDetector;
use crate::user::bin::grapher::Grapher; use crate::user::bin::grapher::Grapher;
use crate::user::lib::gui_v2;
use crate::user::lib::gui_v2::widgets::GuiComponent;
lazy_static! { lazy_static! {
pub static ref CMD: Mutex<CommandHandler> = Mutex::new(CommandHandler::new()); pub static ref CMD: Mutex<CommandHandler> = Mutex::new(CommandHandler::new());
@@ -177,10 +181,24 @@ async fn exec() -> Result<(), Error> {
timer(); timer();
} }
"test_features" => { "test_features" => {
use crate::std::random::Random;
println!("{}", Random::int(0, 10)); std::io::Screen::application_mode();
// use crate::user::lib::libgui;
// libgui::libgui_core::test_elements(); let mut container = gui_v2::widgets::Container::new(
gui_v2::widgets::Position::new(2, 2),
gui_v2::widgets::Dimensions::new(10, 10),
true,
);
let res = container.render().unwrap().render();
let mut elem = ColouredElement {
frame: res as Vec<Vec<ScreenChar>>,
dimensions: (container.dimensions.x as u8, container.dimensions.y as u8),
};
elem.render((2, 2)).unwrap();
} }
_ => { _ => {
return Err(Error::UnknownCommand( return Err(Error::UnknownCommand(
+1 -1
View File
@@ -1,2 +1,2 @@
mod widgets; pub mod widgets;
+65 -21
View File
@@ -1,6 +1,8 @@
use alloc::boxed::Box;
use alloc::string::String; use alloc::string::String;
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::slice::from_mut;
use crate::kernel::render::ScreenChar; use crate::kernel::render::ScreenChar;
use crate::printerr; use crate::printerr;
use crate::user::lib::gui_v2::widgets::XorY::Both; use crate::user::lib::gui_v2::widgets::XorY::Both;
@@ -11,7 +13,13 @@ pub struct Position {
pub y: usize, pub y: usize,
} }
#[derive(Copy, Clone)] impl Position {
pub fn new(x: usize, y: usize) -> Position {
Position { x, y }
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum XorY { pub enum XorY {
X, X,
Y, Y,
@@ -19,6 +27,7 @@ pub enum XorY {
None, None,
} }
impl XorY { impl XorY {
pub fn setx(&mut self) { pub fn setx(&mut self) {
if self == &XorY::None { if self == &XorY::None {
@@ -37,6 +46,7 @@ impl XorY {
} }
#[derive(Debug)]
pub enum GuiError { pub enum GuiError {
OutOfBounds(XorY) OutOfBounds(XorY)
} }
@@ -44,7 +54,7 @@ pub enum GuiError {
pub type Dimensions = Position; pub type Dimensions = Position;
pub type ColouredChar = ScreenChar; pub type ColouredChar = ScreenChar;
#[derive(Copy, Clone)] #[derive(Clone)]
pub struct Frame { pub struct Frame {
position: Position, position: Position,
dimensions: Dimensions, dimensions: Dimensions,
@@ -52,12 +62,12 @@ pub struct Frame {
} }
impl Frame { impl Frame {
pub fn new(position: Position, dimensions: Dimensions) -> Frame { pub fn new(position: Position, dimensions: Dimensions) -> Result<Frame, GuiError> {
Frame { Ok(Frame {
position, position,
dimensions, dimensions,
frame: vec![vec![ScreenChar::null(); dimensions.x]; dimensions.y], frame: vec![vec![ScreenChar::null(); dimensions.x]; dimensions.y],
} })
} }
pub fn render(&self) -> Vec<Vec<ColouredChar>> { pub fn render(&self) -> Vec<Vec<ColouredChar>> {
self.frame.clone() self.frame.clone()
@@ -100,7 +110,7 @@ impl Frame {
if should_panic { if should_panic {
panic!( panic!(
"Element is to large to be rendered {} {}", "Element is to large to be rendered {} {}",
.dimensions().y + element.position().y, element.dimensions().y + element.position().y,
self.dimensions.y self.dimensions.y
) )
} else { } else {
@@ -119,35 +129,69 @@ impl Frame {
pub trait GuiComponent { pub trait GuiComponent {
fn render(&self) -> Frame; fn render(&self) -> Result<Frame, GuiError>;
} }
pub struct Container { pub struct Container {
pub frame: Vec<Vec<ColouredChar>>, pub frame: Vec<Vec<ColouredChar>>,
pub elements: Vec<dyn GuiComponent>, pub elements: Vec<Box<dyn GuiComponent>>,
pub position: Position, pub position: Position,
pub dimensions: Dimensions, pub dimensions: Dimensions,
pub outlined: bool,
} }
impl Container {
pub fn new(position: Position, dimensions: Dimensions, outlined: bool) -> Container {
Container {
frame: vec![vec![ScreenChar::null(); dimensions.x]; dimensions.y],
elements: Vec::new(),
position,
dimensions,
outlined,
}
}
fn render_outline(&self, frame: &mut Frame) {
// draws the sides of the container
for i in 0..frame.dimensions.x {
frame.set_pos(Position::new(i, 0), ColouredChar::white('│' as u8));
frame.set_pos(Position::new(i, frame.dimensions.y - 1), ColouredChar::white('│' as u8));
}
// draws the top and bottom of the container
for i in 0..frame.dimensions.y {
frame.set_pos(Position::new(0, i), ColouredChar::white('─' as u8));
frame.set_pos(Position::new(frame.dimensions.x - 1, i), ColouredChar::white('─' as u8));
}
// draws the corners of the container
frame.set_pos(Position::new(0, 0), ColouredChar::white('┌' as u8));
frame.set_pos(Position::new(self.dimensions.x - 1, 0), ColouredChar::white('┐' as u8));
frame.set_pos(Position::new(0, self.dimensions.y - 1), ColouredChar::white('└' as u8));
frame.set_pos(Position::new(self.dimensions.x - 1, self.dimensions.y - 1), ColouredChar::white('┘' as u8));
}
}
impl GuiComponent for Container { impl GuiComponent for Container {
fn render(&self) -> Result<Frame, GuiError> { fn render(&self) -> Result<Frame, GuiError> {
let mut result = Frame::new(self.position, self.dimensions)?;
let mut frame = Frame::new(self.position, self.dimensions); for widget in &self.elements {
let frame = widget.render()?;
for element in &self.elements { match result.render_bounds_check(&frame, true) { // TODO: this needs to be set to false for production
match frame.render_bounds_check(element, true) { // TODO: this needs to be set to false for production Ok(()) => result.render_element(&frame),
Ok(()) => { Err(e) => return Err(GuiError::OutOfBounds(e)),
let r = (*element).render();
frame.render_element(&r);
}
Err(e) => {
return Err(GuiError::OutOfBounds(e));
}
} }
} }
Ok(frame) if self.outlined {
self.render_outline(&mut result);
}
Ok(result)
} }
} }