updates
updated grapher to use new widtgets system (not working yet but close) made a basic app using the widgets system implemented CgTextEdit for CgLineEdit (now fully working, but there may be bugs so i'll address them tomorrow)
This commit is contained in:
@@ -261,10 +261,16 @@ impl Renderer {
|
||||
if self.application_mode { return; }; // only in terminal mode
|
||||
self.term_buffer.push([ScreenChar::null(); BUFFER_WIDTH]);
|
||||
self.col_pos = 0;
|
||||
if self.term_buffer.len() > 100 {
|
||||
self.term_buffer.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
fn internal_lastline(&mut self) { // goes back to previous line and shifts all lines down
|
||||
if self.application_mode { return; };
|
||||
if self.term_buffer.len() <= 25 {
|
||||
self.term_buffer.insert(0, [ScreenChar::null(); BUFFER_WIDTH]);
|
||||
}
|
||||
self.term_buffer.pop();
|
||||
self.col_pos = BUFFER_WIDTH;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use x86_64::instructions::interrupts;
|
||||
|
||||
use conquer_once::spin::OnceCell;
|
||||
use crossbeam_queue::ArrayQueue;
|
||||
use crate::println;
|
||||
use crate::{println, serial_println};
|
||||
|
||||
use core::{pin::Pin, task::{Poll, Context}};
|
||||
use futures_util::stream::Stream;
|
||||
@@ -15,8 +15,6 @@ use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1, Ke
|
||||
use crate::print;
|
||||
use crate::kernel::render::RENDERER;
|
||||
use alloc::{string::String};
|
||||
use core::ascii::Char;
|
||||
use crate::kernel::tasks::keyboard::CharOrKeystroke::Char;
|
||||
|
||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||
static SCANCODE_QUEUE: OnceCell<ArrayQueue<u8>> = OnceCell::uninit();
|
||||
@@ -36,6 +34,7 @@ enum CharOrKeystroke {
|
||||
Keystroke(KeyCode),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum KeyStroke {
|
||||
Char(char),
|
||||
Ctrl,
|
||||
@@ -46,6 +45,9 @@ pub enum KeyStroke {
|
||||
RShift,
|
||||
Meta,
|
||||
RMeta,
|
||||
Backspace,
|
||||
Left,
|
||||
Right,
|
||||
None,
|
||||
}
|
||||
|
||||
@@ -60,6 +62,9 @@ impl KeyStroke {
|
||||
KeyCode::ShiftRight => KeyStroke::RShift,
|
||||
KeyCode::WindowsLeft => KeyStroke::Meta,
|
||||
KeyCode::WindowsRight => KeyStroke::RMeta,
|
||||
KeyCode::Backspace => KeyStroke::Backspace,
|
||||
KeyCode::ArrowLeft => KeyStroke::Left,
|
||||
KeyCode::ArrowRight => KeyStroke::Right,
|
||||
_ => KeyStroke::None,
|
||||
}
|
||||
}
|
||||
@@ -81,20 +86,12 @@ impl KeyboardHandler {
|
||||
if let Ok(Some(key_event)) = self.keyboard.add_byte(scancode) {
|
||||
if let Some(key) = self.keyboard.process_keyevent(key_event) {
|
||||
match key {
|
||||
DecodedKey::Unicode(character) => {
|
||||
if character == b'\x08' as char { // checks if the character is a backspace
|
||||
interrupts::without_interrupts(|| {
|
||||
RENDERER.lock().backspace(); // runs the backspace function of the vga buffer to remove the last character
|
||||
});
|
||||
return None;
|
||||
} else {
|
||||
return Some(KeyStroke::Char(character));
|
||||
}
|
||||
},
|
||||
DecodedKey::Unicode(character) => return Some(KeyStroke::Char(character)),
|
||||
DecodedKey::RawKey(key) => {
|
||||
print!("{:?}", key)
|
||||
match key {
|
||||
KeyCode::NOn
|
||||
print!("{:?}", key);
|
||||
match KeyStroke::from_keycode(key) {
|
||||
KeyStroke::None => (),
|
||||
k => return Some(k)
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -108,11 +105,8 @@ impl KeyboardHandler {
|
||||
loop {
|
||||
match self.get_keystroke_inner().await {
|
||||
Some(c) => match c {
|
||||
CharOrKeystroke::Char(c) => return KeyStroke::Char(c),
|
||||
CharOrKeystroke::Keystroke(c) => match KeyStroke::from_keycode(c) {
|
||||
KeyStroke::None => (),
|
||||
key => return key
|
||||
}
|
||||
KeyStroke::None => (),
|
||||
c => return c
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
@@ -157,8 +151,16 @@ impl KeyboardHandler {
|
||||
None => { val.pop(); continue; },
|
||||
};
|
||||
|
||||
if let CharOrKeystroke::Char(c) = character {
|
||||
print!("{}", character);
|
||||
if let KeyStroke::Char(c) = character {
|
||||
if c == '\x08' {
|
||||
val.pop();
|
||||
interrupts::without_interrupts(|| {
|
||||
RENDERER.lock().backspace(); // runs the backspace function of the vga buffer to remove the last character
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
print!("{}", c);
|
||||
let (c, execute): (char, bool) = match c {
|
||||
'\n' => (c, true),
|
||||
_ => (c, false),
|
||||
|
||||
+10
-13
@@ -96,8 +96,7 @@ impl Frame {
|
||||
|
||||
for line in elemstr.split("\n") {
|
||||
element.frame.push(
|
||||
line
|
||||
.chars()
|
||||
line.chars()
|
||||
.map(|c| ColouredChar::new(c))
|
||||
.collect::<Vec<ColouredChar>>()
|
||||
);
|
||||
@@ -105,7 +104,7 @@ impl Frame {
|
||||
|
||||
for row in element.clone().frame {
|
||||
let n = row.len();
|
||||
if n > element.dimensions.x as usize {
|
||||
if n > element.dimensions.x {
|
||||
element.dimensions.x = n;
|
||||
}
|
||||
}
|
||||
@@ -116,21 +115,19 @@ impl Frame {
|
||||
self.frame.clone()
|
||||
}
|
||||
|
||||
pub fn render_to_screen(&self) -> Result<(), RenderError> {
|
||||
pub fn write_to_screen(&self) -> Result<(), RenderError> {
|
||||
let mut frame: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT] = [[ScreenChar::null(); BUFFER_WIDTH]; BUFFER_HEIGHT];
|
||||
for (i, row) in self.frame.iter().enumerate() {
|
||||
for (j, col) in row.iter().enumerate() {
|
||||
//println!("{} {} {}", i, j, col);
|
||||
frame[i + self.position.y as usize][j + self.position.x as usize] = col.as_screen_char();
|
||||
frame[i + self.position.y][j + self.position.x] = col.as_screen_char();
|
||||
};
|
||||
}
|
||||
RENDERER.lock().render_frame(frame);
|
||||
Ok(())
|
||||
}
|
||||
pub fn position(&self) -> Position {
|
||||
pub fn get_position(&self) -> Position {
|
||||
self.position
|
||||
}
|
||||
|
||||
pub fn set_position(&mut self, position: Position) {
|
||||
self.position = position
|
||||
}
|
||||
@@ -140,7 +137,7 @@ impl Frame {
|
||||
pub fn write(&mut self, position: Position, char: ColouredChar) {
|
||||
self.frame[position.y][position.x] = char
|
||||
}
|
||||
pub fn render_element(&mut self, other: &Frame) {
|
||||
pub fn place_child_element(&mut self, other: &Frame) {
|
||||
for (i, row) in other.frame.iter().enumerate() {
|
||||
for (j, chr) in row.iter().enumerate() {
|
||||
self.frame[i + other.position.y][j + other.position.x] = *chr
|
||||
@@ -152,20 +149,20 @@ impl Frame {
|
||||
|
||||
let (mut x, mut y) = (false, false);
|
||||
|
||||
if element.dimensions().x + element.position().x > self.dimensions.x {
|
||||
if element.dimensions().x + element.get_position().x > self.dimensions.x {
|
||||
if should_panic { panic!(
|
||||
"Element is to large to be rendered {} {}",
|
||||
element.dimensions().x + element.position().x,
|
||||
element.dimensions().x + element.get_position().x,
|
||||
self.dimensions.x
|
||||
)} else {
|
||||
x = true;
|
||||
}
|
||||
}
|
||||
|
||||
if element.dimensions().y + element.position().y > self.dimensions.y {
|
||||
if element.dimensions().y + element.get_position().y > self.dimensions.y {
|
||||
if should_panic { panic!(
|
||||
"Element is to large to be rendered {} {}",
|
||||
element.dimensions().y + element.position().y,
|
||||
element.dimensions().y + element.get_position().y,
|
||||
self.dimensions.y
|
||||
)} else {
|
||||
y = true;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
kernel::render::{RENDERER, self},
|
||||
kernel::tasks::keyboard::{KEYBOARD, KeyStroke},
|
||||
kernel::tasks::keyboard::{KEYBOARD},
|
||||
};
|
||||
pub use crate::kernel::tasks::keyboard::KeyStroke;
|
||||
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
@@ -17,6 +18,7 @@ use crate::std::frame::RenderError;
|
||||
|
||||
pub struct Stdin {}
|
||||
impl Stdin {
|
||||
pub const BACKSPACE: char = b'\x08' as char;
|
||||
/// waits for the user to type in a string and press enter | blocking
|
||||
pub async fn readline() -> String {
|
||||
let string = KEYBOARD.lock().get_string().await;
|
||||
@@ -24,13 +26,13 @@ impl Stdin {
|
||||
}
|
||||
|
||||
/// waits for a keystroke | blocking
|
||||
pub async fn keystroke() -> char {
|
||||
pub async fn keystroke() -> KeyStroke {
|
||||
let chr = KEYBOARD.lock().get_keystroke().await;
|
||||
chr
|
||||
}
|
||||
|
||||
/// gets the next keystroke if any is present | non blocking
|
||||
pub fn try_keystroke() -> Option<char> {
|
||||
pub fn try_keystroke() -> Option<KeyStroke> {
|
||||
let chr = KEYBOARD.lock().try_keystroke();
|
||||
chr
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user