worked on rendering code
worked on code for libgui for rendering a user interface
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@
|
||||
#![feature(global_asm)]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use spin::Mutex;
|
||||
|
||||
|
||||
pub mod system;
|
||||
pub mod user;
|
||||
|
||||
+1
-2
@@ -9,7 +9,6 @@ use CrystalOS::{println, print, println_log, print_log};
|
||||
use CrystalOS::kernel::tasks::{Task, executor::Executor};
|
||||
use bootloader::{BootInfo, entry_point};
|
||||
extern crate alloc;
|
||||
use alloc::{boxed::Box, vec, vec::Vec, rc::Rc, string, string::String};
|
||||
use CrystalOS::user::bin::shell;
|
||||
|
||||
#[cfg(not(test))]
|
||||
@@ -32,7 +31,7 @@ fn main(boot_info: &'static BootInfo) -> ! {
|
||||
use CrystalOS::kernel::allocator;
|
||||
use CrystalOS::kernel::memory;
|
||||
use CrystalOS::kernel::memory::BootInfoFrameAllocator;
|
||||
use x86_64::{structures::paging::{Page, Translate}, VirtAddr};
|
||||
use x86_64::VirtAddr;
|
||||
|
||||
CrystalOS::init();
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ extern "x86-interrupt" fn double_fault_handler(stack_frame: InterruptStackFrame,
|
||||
panic!("EXCEPTION: double fault\n{:#?}", stack_frame)
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn timer_interrupt_handler(stack_frame: InterruptStackFrame) {
|
||||
extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||
unsafe {
|
||||
GLOBALTIMER.lock().inc();
|
||||
PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||
|
||||
@@ -186,7 +186,10 @@ impl Renderer {
|
||||
'┐' => 191,
|
||||
'└' => 192,
|
||||
'┘' => 217,
|
||||
'┌' => 218,
|
||||
'┌' => 218,
|
||||
'┼' => 197,
|
||||
'░' => 176,
|
||||
'▓' => 178,
|
||||
_ => { return None; }
|
||||
};
|
||||
Some(res)
|
||||
|
||||
@@ -52,11 +52,14 @@ pub struct Element {
|
||||
frame: Vec<Vec<char>>,
|
||||
dimensions: (u8, u8)
|
||||
}
|
||||
|
||||
/// elements can be created using their from_str() method
|
||||
/// you can then render the element to the current frame using the render() method
|
||||
/// the position of the element by passing a tuple (x,y) to render()
|
||||
///
|
||||
/// nothing will appear on the screen until the frame is actually
|
||||
/// nothing will appear on the screen until the frame is actually rendered by
|
||||
/// the render_frame method on the renderer
|
||||
|
||||
impl Element {
|
||||
pub fn from_str(elemstr: String) -> Self {
|
||||
let mut element = Element { frame: Vec::<Vec<char>>::new(), dimensions: (0, 0) };
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
use alloc::{boxed::Box, string::{String, ToString}, vec::Vec};
|
||||
use alloc::{string::{String, ToString}, vec::Vec};
|
||||
use rand::{Rng, SeedableRng, rngs::SmallRng, RngCore};
|
||||
use spin::Mutex;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
@@ -109,7 +109,7 @@ impl Application for GameLoop {
|
||||
}
|
||||
|
||||
fn random() -> u64 {
|
||||
let mut r = random::Random::int(0, 125) as u64;
|
||||
let r = random::Random::int(0, 125) as u64;
|
||||
r
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -3,5 +3,5 @@ pub mod crystal_rpg;
|
||||
pub mod crystalfetch;
|
||||
pub mod rickroll;
|
||||
pub mod shell;
|
||||
pub mod shellrewrite;
|
||||
//pub mod shellrewrite;
|
||||
pub mod tasks;
|
||||
|
||||
@@ -131,7 +131,10 @@ async fn exec() -> Result<(), Error> {
|
||||
use crate::std::io;
|
||||
io::mkfs();
|
||||
}
|
||||
|
||||
"test_features" => {
|
||||
use crate::user::lib::libgui;
|
||||
libgui::libgui_core::test_elements();
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::UnknownCommand(
|
||||
"command not yet implemented".to_string(),
|
||||
|
||||
@@ -131,14 +131,14 @@ impl TaskList {
|
||||
}
|
||||
pub fn add(&mut self, content: String) -> Result<(), Error> {
|
||||
let task = Task::new(self.next(), content);
|
||||
let id = task.taskid.clone();
|
||||
let _id = task.taskid.clone();
|
||||
self.tasks.push(task);
|
||||
Ok(())
|
||||
}
|
||||
pub fn remove(&mut self, id: usize) -> Result<(), Error> {
|
||||
pub fn remove(&mut self, _id: usize) -> Result<(), Error> {
|
||||
for (i, task) in self.tasks.clone().iter().enumerate() {
|
||||
match task.taskid {
|
||||
id => { self.tasks.remove(i); },
|
||||
_id => { self.tasks.remove(i); },
|
||||
_ => { return Err(Error::CommandFailed(String::from("this task does not exist"))); },
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
use crate::std::io::Frame;
|
||||
use alloc::{vec::Vec, vec, boxed::Box, string::ToString};
|
||||
use crate::kernel::render::{BUFFER_WIDTH, BUFFER_HEIGHT, RENDERER};
|
||||
use crate::{println, print};
|
||||
/*
|
||||
|
||||
- this library will provide useful structures for creating simple
|
||||
command line based interfaces using ascii
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/// all interface elements must implement this trait in order to be
|
||||
/// rendered on the screen
|
||||
trait Element { // default behaviour for all elements
|
||||
|
||||
fn render(&self) -> (Vec<Vec<char>>, (usize, usize)) { // recursive method for rendering the
|
||||
// specified frame to the screen
|
||||
// insert rendering code for specific frame here
|
||||
// this should also render all children of the element
|
||||
(Vec::<Vec<char>>::new(), (0, 0))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub struct Container { // a simple container objects for grouping
|
||||
// other containers together
|
||||
frame: Vec<Vec<char>>,
|
||||
elements: Vec<Box<dyn Element>>,
|
||||
position: (usize, usize), // x,y
|
||||
//
|
||||
outlined: bool,
|
||||
dimensions: (usize, usize), // x,y
|
||||
}
|
||||
|
||||
impl Container {
|
||||
|
||||
fn new(position: (usize, usize), dimensions: (usize, usize), outlined: bool) -> Container {
|
||||
Self {
|
||||
frame: vec![vec![' '; dimensions.0 as usize]; dimensions.1 as usize],
|
||||
elements: Vec::new(),
|
||||
position,
|
||||
outlined,
|
||||
dimensions,
|
||||
}
|
||||
}
|
||||
fn place(&self, element: Vec<Vec<char>>) {
|
||||
return // unimplemented
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Element for Container {
|
||||
|
||||
fn render(&self) -> (Vec<Vec<char>>, (usize, usize)) { // returns all elements as a single frame
|
||||
|
||||
let mut charmap = Vec::<Vec<char>>::new();
|
||||
|
||||
let mut frstline: Vec<char>;
|
||||
let mut midlines: Vec<char>;
|
||||
let mut lastline: Vec<char>;
|
||||
|
||||
|
||||
if self.outlined {
|
||||
frstline = vec!['┌'];
|
||||
midlines = vec!['│'];
|
||||
lastline = vec!['└'];
|
||||
|
||||
frstline.append(&mut vec!['─'; self.dimensions.0 -2]);
|
||||
midlines.append(&mut vec![' '; self.dimensions.0 -2]);
|
||||
lastline.append(&mut vec!['─'; self.dimensions.0 -2]);
|
||||
|
||||
frstline.append(&mut vec!['┐']);
|
||||
midlines.append(&mut vec!['│']);
|
||||
lastline.append(&mut vec!['┘']);
|
||||
|
||||
|
||||
charmap.push(frstline);
|
||||
for _ in 0..self.dimensions.1 -2 {
|
||||
charmap.push(midlines.clone());
|
||||
}
|
||||
charmap.push(lastline);
|
||||
|
||||
}
|
||||
|
||||
// render child elements
|
||||
|
||||
for element in &self.elements {
|
||||
let r = (*element).render();
|
||||
|
||||
// rendering code for child elements goes here
|
||||
|
||||
|
||||
// code to render the object at the position marked by offset within the container
|
||||
|
||||
|
||||
for (i, row) in r.0.iter().enumerate() {
|
||||
for (j, chr) in row.iter().enumerate() { // r.0 is the rendered element
|
||||
// r.1.0 is the x offset
|
||||
charmap[i + r.1.1][j + r.1.0] = *chr; // r.1.1 is the y offset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (charmap, self.position);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub struct IndicatorBar {
|
||||
length: usize,
|
||||
filled: usize,
|
||||
abs: usize,
|
||||
position: (usize, usize),
|
||||
}
|
||||
|
||||
impl IndicatorBar {
|
||||
fn new(position: (usize, usize), length: usize) -> IndicatorBar {
|
||||
IndicatorBar { position, length, abs: 0, filled: 0 }
|
||||
}
|
||||
fn set_value(&mut self, value: usize) { // takes a value from 1-100%
|
||||
// and turns it into a corresponding length filled
|
||||
self.filled = value
|
||||
}
|
||||
}
|
||||
|
||||
impl Element for IndicatorBar {
|
||||
fn render(&self) -> (Vec<Vec<char>>, (usize, usize)) {
|
||||
let numlen = (self.abs.to_string().as_str()).len();
|
||||
let relfilled = (self.filled as f64 / 100.0 * ((self.length - numlen) as f64)) as usize;
|
||||
|
||||
let mut line = Vec::<char>::new();
|
||||
line.append(&mut (self.abs.to_string().chars().collect()));
|
||||
line.append(&mut vec!['▓'; relfilled]);
|
||||
line.append(&mut vec!['░'; self.length-numlen-relfilled]);
|
||||
|
||||
|
||||
let mut rendered = Vec::new();
|
||||
rendered.push(line);
|
||||
|
||||
|
||||
println!("RENDERED: {:?}", rendered);
|
||||
|
||||
return (rendered, (self.position))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// functions that deal with the rendering and interaction between objects being
|
||||
// rendered.
|
||||
|
||||
pub fn render_frame(elements: Vec<Container>) {
|
||||
let mut buffer: Frame = [[' '; BUFFER_WIDTH]; BUFFER_HEIGHT];
|
||||
|
||||
for frame in elements.iter() {
|
||||
|
||||
let f = frame.render();
|
||||
|
||||
for (i, row) in f.0.iter().enumerate() {
|
||||
for (j, chr) in row.iter().enumerate() {
|
||||
let mut current = &buffer[i + f.1.1][j + f.1.0];
|
||||
let newchar = overlap_check(*current, *chr);
|
||||
buffer[i + f.1.1][j + f.1.0] = newchar;
|
||||
|
||||
//print!("{}", buffer[i+frame.position.1][j+frame.position.0]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//println!("{:?}", buffer);
|
||||
|
||||
RENDERER.lock().render_frame(buffer)
|
||||
}
|
||||
|
||||
pub fn overlap_check(oldchar: char, newchar: char) -> char {
|
||||
match (oldchar, newchar) {
|
||||
//┌│└ ┐┘─
|
||||
('│', '─')|('┌', '┘')|('└', '┐') => '┼',
|
||||
('┌', '└') => '├',
|
||||
('┐', '┐') => '┤',
|
||||
|
||||
(_, _) => newchar
|
||||
}
|
||||
}
|
||||
|
||||
// function to return a charmap of the outline of an object
|
||||
|
||||
fn gen_outline(dimensions: (usize, usize)) -> Vec<Vec<char>> {
|
||||
let mut charmap = Vec::<Vec<char>>::new();
|
||||
|
||||
let mut frstline = vec!['┌'];
|
||||
let mut midlines = vec!['│'];
|
||||
let mut lastline = vec!['└'];
|
||||
|
||||
frstline.append(&mut vec!['─'; dimensions.0 -2]);
|
||||
midlines.append(&mut vec![' '; dimensions.0 -2]);
|
||||
lastline.append(&mut vec!['─'; dimensions.0 -2]);
|
||||
|
||||
frstline.append(&mut vec!['┐']);
|
||||
midlines.append(&mut vec!['│']);
|
||||
lastline.append(&mut vec!['┘']);
|
||||
|
||||
|
||||
charmap.push(frstline);
|
||||
for _ in 0..dimensions.1 -2 {
|
||||
charmap.push(midlines.clone());
|
||||
}
|
||||
charmap.push(lastline);
|
||||
|
||||
return charmap
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// testing functions
|
||||
|
||||
pub fn test_elements() {
|
||||
println!("e");
|
||||
|
||||
let mut containers = Vec::<Container>::new();
|
||||
|
||||
//for _ in 0..10 {
|
||||
// containers.push(generate_box());
|
||||
//}
|
||||
|
||||
containers.push(Container::new((5, 5), (15, 5), true));
|
||||
containers.push(Container::new((10, 3), (50, 15), true));
|
||||
|
||||
let mut bar = IndicatorBar::new((10, 10), 12);
|
||||
let mut bar2 = IndicatorBar::new((10, 11), 12);
|
||||
|
||||
|
||||
bar.set_value(43);
|
||||
bar.abs = 101;
|
||||
bar2.set_value(14);
|
||||
bar2.abs= 15;
|
||||
containers[1].elements.push(Box::new(bar));
|
||||
containers[1].elements.push(Box::new(bar2));
|
||||
|
||||
|
||||
render_frame(containers);
|
||||
return
|
||||
}
|
||||
|
||||
// function to generate a box in a random location on the screen.
|
||||
|
||||
fn generate_box() -> Container {
|
||||
use crate::std::random::Random;
|
||||
let width = Random::int(5, 20);
|
||||
let height = Random::int(5, 10);
|
||||
let xoffset = Random::int(5, 50);
|
||||
let yoffset = Random::int(5, 10);
|
||||
Container::new((width, height), (xoffset, yoffset), true)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod libgui_core;
|
||||
pub mod libgui_elements;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod libgui;
|
||||
|
||||
Reference in New Issue
Block a user